├── .gitignore ├── .nojekyll ├── README.md ├── _ ├── sounds │ └── amen.wav ├── style.css └── utils.js ├── demo └── time-stretch │ ├── README.md │ ├── index.html │ ├── index.js │ ├── lib │ ├── TimeStretchBufferNode.js │ └── index.js │ └── package.json ├── index.js ├── links ├── index-of-web-audio-weekly │ ├── README.md │ └── make.rb ├── music-programming-languages.md ├── source-code-of-web-audio-api.md ├── specification.md └── tutorials.md ├── node ├── CompareEqualToNode │ ├── README.md │ ├── createCompareEqualToNode.js │ ├── img │ │ ├── CompareEqualToNode.png │ │ └── CompareEqualToNodePlot.png │ └── index.html ├── CompareGreaterThanNode │ ├── README.md │ ├── createCompareGreaterThanNode.js │ ├── img │ │ ├── CompareGreaterThanNode.png │ │ └── CompareGreaterThanNodePlot.png │ └── index.html ├── CompareGreaterThanOrEqualToNode │ ├── README.md │ ├── createCompareGreaterThanOrEqualToNode.js │ ├── img │ │ ├── CompareGreaterThanOrEqualToNode.png │ │ └── CompareGreaterThanOrEqualToNodePlot.png │ └── index.html ├── CompareLessThanNode │ ├── README.md │ ├── createCompareLessThanNode.js │ ├── img │ │ ├── CompareLessThanNode.png │ │ └── CompareLessThanNodePlot.png │ └── index.html ├── CompareLessThanOrEqualToNode │ ├── README.md │ ├── createCompareLessThanOrEqualToNode.js │ ├── img │ │ ├── CompareLessThanOrEqualToNode.png │ │ └── CompareLessThanOrEqualToNodePlot.png │ └── index.html ├── CompareNotEqualToNode │ ├── README.md │ ├── createCompareNotEqualToNode.js │ ├── img │ │ ├── CompareNotEqualToNode.png │ │ └── CompareNotEqualToNodePlot.png │ └── index.html ├── CrossFadeNode │ ├── CrossFadeNodeWaveShape.py │ ├── README.md │ ├── createCrossFadeNode.js │ ├── img │ │ ├── CrossFadeNode.png │ │ ├── CrossFadeNodePlot.png │ │ └── CrossFadeNodeWaveShape.png │ └── index.html ├── IsNegativeNode │ ├── IsNegativeNodeWaveShape.py │ ├── README.md │ ├── createIsNegativeNode.js │ ├── img │ │ ├── IsNegativeNode.png │ │ ├── IsNegativeNodePlot.png │ │ └── IsNegativeNodeWaveShape.png │ └── index.html ├── IsNotZeroNode │ ├── IsNotZeroNodeWaveShape.py │ ├── README.md │ ├── createIsNotZeroNode.js │ ├── img │ │ ├── IsNotZeroNode.png │ │ ├── IsNotZeroNodePlot.png │ │ └── IsNotZeroNodeWaveShape.png │ └── index.html ├── IsPositiveNode │ ├── IsPositiveNodeWaveShape.py │ ├── README.md │ ├── createIsPositiveNode.js │ ├── img │ │ ├── IsPositiveNode.png │ │ ├── IsPositiveNodePlot.png │ │ └── IsPositiveNodeWaveShape.png │ └── index.html ├── IsPositiveOrZeroNode │ ├── IsPositiveOrZeroNodeWaveShape.py │ ├── README.md │ ├── createIsPositiveOrZeroNode.js │ ├── img │ │ ├── IsPositiveOrZeroNode.png │ │ ├── IsPositiveOrZeroNodePlot.png │ │ └── IsPositiveOrZeroNodeWaveShape.png │ └── index.html ├── IsZeroNode │ ├── IsZeroNodeWaveShape.py │ ├── README.md │ ├── createIsZeroNode.js │ ├── img │ │ ├── IsZeroNode.png │ │ ├── IsZeroNodePlot.png │ │ └── IsZeroNodeWaveShape.png │ └── index.html ├── MathAbsNode │ ├── README.md │ ├── createMathAbsNode.js │ ├── img │ │ ├── MathAbsNode.png │ │ └── MathAbsNodePlot.png │ └── index.html ├── MathAddNode │ ├── README.md │ ├── createMathAddNode.js │ ├── img │ │ ├── MathAddNode.png │ │ └── MathAddNodePlot.png │ └── index.html ├── MathDivideNode │ ├── MathDivideNodeWaveShape.py │ ├── README.md │ ├── createMathDivideNode.js │ ├── img │ │ ├── MathDivideNode.png │ │ ├── MathDivideNodePlot.png │ │ └── MathDivideNodeWaveShape.png │ └── index.html ├── MathInvertNode │ ├── README.md │ ├── createMathInvertNode.js │ ├── img │ │ ├── MathInvertNode.png │ │ └── MathInvertNodePlot.png │ └── index.html ├── MathMaxNode │ ├── README.md │ ├── createMathMaxNode.js │ ├── img │ │ ├── MathMaxNode.png │ │ └── MathMaxNodePlot.png │ └── index.html ├── MathMultiplyNode │ ├── README.md │ ├── createMathMultiplyNode.js │ ├── img │ │ ├── MathMultiplyNode.png │ │ └── MathMultiplyNodePlot.png │ └── index.html ├── MathSignNode │ ├── MathSignNodeWaveShape.py │ ├── README.md │ ├── createMathSignNode.js │ ├── img │ │ ├── MathSignNode.png │ │ ├── MathSignNodePlot.png │ │ └── MathSignNodeWaveShape.png │ └── index.html ├── MathSubtractNode │ ├── README.md │ ├── createMathSubtractNode.js │ ├── img │ │ ├── MathSubtractNode.png │ │ └── MathSubtractNodePlot.png │ └── index.html ├── SwitchNode │ ├── README.md │ ├── SwitchNodeWaveShape.py │ ├── createSwitchNode.js │ ├── img │ │ ├── SwitchNode.png │ │ ├── SwitchNodePlot.png │ │ └── SwitchNodeWaveShape.png │ └── index.html └── ZeroCrossingNode │ ├── README.md │ ├── createZeroCrossingNode.js │ ├── img │ ├── ZeroCrossingNode.png │ └── ZeroCrossingNodePlot.png │ └── index.html └── research ├── audio-node-default-channel-configuration.md ├── audio-param-set-value-curve-at-time-interpolation ├── README.md ├── img │ └── comparison.png ├── index.html ├── value-curve.js └── value-curve.py ├── audio-utils-the-valid-range-of-parameters.md └── wave-shaper-node-interpolation ├── README.md ├── img └── comparison.png ├── index.html ├── wave-shaper.py └── wave-sheper.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_STORE 2 | *.graffle 3 | node-debug.log 4 | node_modules/ 5 | -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/.nojekyll -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web Audio API Laboratory 2 | 3 | This repository is a collection of experimental code for Web Audio API. 4 | 5 | ## Works 6 | 7 | ### demo 8 | 9 | - [Time Stretch Demo](demo/time-stretch) 10 | 11 | ### links 12 | 13 | - [Index of Web Audio Weekly](links/index-of-web-audio-weekly) 14 | - [Music Programming Languages](links/music-programming-languages.md) 15 | - [Source Code of Web Audio API](links/source-code-of-web-audio-api.md) 16 | - [Specification](links/specification.md) 17 | - [Tutorials](links/tutorials.md) 18 | 19 | ### node 20 | 21 | - [CompareEqualToNode](node/CompareEqualToNode) 22 | - [CompareGreaterThanNode](node/CompareGreaterThanNode) 23 | - [CompareGreaterThanOrEqualToNode](node/CompareGreaterThanOrEqualToNode) 24 | - [CompareLessThanNode](node/CompareLessThanNode) 25 | - [CompareLessThanOrEqualToNode](node/CompareLessThanOrEqualToNode) 26 | - [CompareNotEqualToNode](node/CompareNotEqualToNode) 27 | - [CrossFadeNode](node/CrossFadeNode) 28 | - [IsNegativeNode](node/IsNegativeNode) 29 | - [IsNotZeroNode](node/IsNotZeroNode) 30 | - [IsPositiveNode](node/IsPositiveNode) 31 | - [IsPositiveOrZeroNode](node/IsPositiveOrZeroNode) 32 | - [IsZeroNode](node/IsZeroNode) 33 | - [MathAbsNode](node/MathAbsNode) 34 | - [MathAddNode](node/MathAddNode) 35 | - [MathDivideNode](node/MathDivideNode) 36 | - [MathInvertNode](node/MathInvertNode) 37 | - [MathMaxNode](node/MathMaxNode) 38 | - [MathMultiplyNode](node/MathMultiplyNode) 39 | - [MathSignNode](node/MathSignNode) 40 | - [MathSubtractNode](node/MathSubtractNode) 41 | - [SwitchNode](node/SwitchNode) 42 | - [ZeroCrossingNode](node/ZeroCrossingNode) 43 | 44 | ### research 45 | 46 | - [AudioNode - Default Channel Configuration](research/audio-node-default-channel-configuration.md) 47 | - [AudioParam - setValueCurveAtTime Interpolation](research/audio-param-set-value-curve-at-time-interpolation) 48 | - [AudioUtils - The Valid Range of Parameters](research/audio-utils-the-valid-range-of-parameters.md) 49 | - [WaveShaperNode - Interpolation](research/wave-shaper-node-interpolation) 50 | 51 | ## License 52 | MIT 53 | -------------------------------------------------------------------------------- /_/sounds/amen.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/_/sounds/amen.wav -------------------------------------------------------------------------------- /_/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | text-decoration: none; 5 | } 6 | 7 | a > h1 { 8 | color: #34495e; 9 | margin: 4px; 10 | } 11 | 12 | .plot { 13 | width: 100%; 14 | height: 480px; 15 | background: #ecf0f1; 16 | } 17 | -------------------------------------------------------------------------------- /_/utils.js: -------------------------------------------------------------------------------- 1 | window.utils = (function() { 2 | "use strict"; 3 | 4 | window.AudioContext = window.AudioContext || window.webkitAudioContext; 5 | window.OfflineAudioContext = window.OfflineAudioContext || window.webkitOfflineAudioContext; 6 | 7 | var utils = {}; 8 | 9 | function SignalPlotter(context, opts) { 10 | opts = opts || {}; 11 | 12 | this.context = context; 13 | this.width = context.canvas.width; 14 | this.height = context.canvas.height; 15 | this.ylim = opts.ylim || [ -1, +1 ]; 16 | this.yticks = opts.yticks || [ -1, -0.5, 0, +0.5, +1 ]; 17 | 18 | this._drawScale(); 19 | } 20 | 21 | SignalPlotter.prototype._drawScale = function() { 22 | var context = this.context; 23 | var x1 = 40, x2 = this.width; 24 | var y1 = 10, y2 = this.height - 10; 25 | var ylim = this.ylim; 26 | var hasDot = this.yticks.some(function(x) { 27 | return Math.floor(x) !== x; 28 | }); 29 | 30 | context.save(); 31 | 32 | context.fillStyle = "#ffffff"; 33 | context.fillRect(0, 0, this.width, this.height); 34 | 35 | context.fillStyle = "#fafafa"; 36 | context.fillRect(40, 10, this.width, this.height - 20); 37 | 38 | context.fillStyle = "#7f8c8d"; 39 | context.strokeStyle = "#e0e0e0" 40 | context.font = "12px monospace"; 41 | 42 | this.yticks.forEach(function(value) { 43 | var text = value.toFixed(hasDot ? 1 : 0); 44 | var m = context.measureText(text).width; 45 | var y = Math.floor(linlin(value, ylim[1], ylim[0], y1, y2)) + 0.5; 46 | 47 | context.beginPath(); 48 | context.moveTo(x1, y); 49 | context.lineTo(x2, y); 50 | context.stroke(); 51 | 52 | context.fillText(text, x1 - 5 - m, y + 4) 53 | }); 54 | 55 | context.restore(); 56 | }; 57 | 58 | SignalPlotter.prototype.plot = function(signal, opts) { 59 | var context = this.context; 60 | var x1 = 40, x2 = this.width; 61 | var y1 = 10, y2 = this.height - 10; 62 | var ylim = this.ylim; 63 | 64 | context.save(); 65 | 66 | Object.keys(opts).forEach(function(key) { 67 | context[key] = opts[key]; 68 | }) 69 | 70 | context.beginPath(); 71 | 72 | for (var i = 0; i < signal.length; i++) { 73 | var x = linlin(i, 0, signal.length, x1, x2); 74 | var y = linlin(signal[i], ylim[1], ylim[0], y1, y2); 75 | 76 | context.lineTo(x, y); 77 | } 78 | 79 | context.stroke(); 80 | 81 | context.restore(); 82 | }; 83 | 84 | function linlin(value, inMin, inMax, outMin, outMax) { 85 | return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin; 86 | } 87 | 88 | function captureSignal(fn, duration) { 89 | var sampleRate = 44100; 90 | var length = Math.floor(duration * sampleRate); 91 | var context = new OfflineAudioContext(1, length, sampleRate); 92 | 93 | fn(context).connect(context.destination); 94 | 95 | context.startRendering(); 96 | 97 | return new Promise(function(resolve) { 98 | context.oncomplete = function(e) { 99 | resolve(e.renderedBuffer.getChannelData(0)); 100 | }; 101 | }); 102 | } 103 | 104 | utils.SignalPlotter = SignalPlotter; 105 | utils.linlin = linlin; 106 | utils.captureSignal = captureSignal; 107 | 108 | return utils; 109 | })(); 110 | -------------------------------------------------------------------------------- /demo/time-stretch/README.md: -------------------------------------------------------------------------------- 1 | # Time Stretch Demo 2 | 3 | http://mohayonao.github.io/waa-lab/demo/time-stretch/ 4 | -------------------------------------------------------------------------------- /demo/time-stretch/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TimeStretch Demo 6 | 7 | 11 | 12 | 13 |
14 |

TimeStretch Demo

15 |
16 | 17 |
18 |
19 |
20 |

{{ name }}

21 |

{{ duration.toFixed(2) }}sec

22 |

23 | drag and drop your audio file (wav or mp3) into this window 24 |

25 |
26 |
27 |
28 |

{{ rate.toFixed(2) }}

29 | 30 |
31 |
32 |

{{ (windowSize * 1000)|0 }} msec

33 | 34 |
35 |
36 |
37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /demo/time-stretch/index.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o { 47 | let dirPath = path.join(__dirname, category); 48 | 49 | if (/^[._]/.test(category) || !isDirectory(dirPath)) { 50 | return; 51 | } 52 | 53 | readMe += `### ${ category }\n\n`; 54 | 55 | fs.readdirSync(dirPath).sort().forEach((fileName) => { 56 | let filePath = path.join(dirPath, fileName); 57 | let title = null; 58 | 59 | if (isDirectory(filePath)) { 60 | title = getTitleFromDirectory(filePath) || fileName; 61 | } else if (isMarkdown(filePath)) { 62 | title = getTitleFromMarkdown(filePath); 63 | } 64 | 65 | if (title) { 66 | readMe += ` - [${ title }](${ category }/${ fileName })\n`; 67 | } 68 | }); 69 | 70 | readMe += "\n"; 71 | }); 72 | 73 | readMe += ReadMeFooter.trimLeft(); 74 | 75 | fs.writeFileSync(path.join(__dirname, "README.md"), readMe); 76 | -------------------------------------------------------------------------------- /links/index-of-web-audio-weekly/README.md: -------------------------------------------------------------------------------- 1 | # Index of Web Audio Weekly 2 | 3 | Web Audio Weekly is a valuable source of the latest topics about the Web Audio API, the Web MIDI API or sound on the web that written by Chris Lowis. 4 | 5 | http://blog.chrislowis.co.uk/waw.html 6 | 7 | :trophy: _68 posts and 453 topics are... awesome!!_ 8 | 9 | --- 10 | 11 | ##### [Web Audio Weekly 68](http://blog.chrislowis.co.uk//waw/2016/08/29/web-audio-weekly-68.html) : 2016-08-29 12 | - BlockDust 13 | - Google’s Omnitone: Spatial audio on the web 14 | - What’s new in Web Audio 15 | - Guitar Amp Simulator in Web Audio 16 | - midi-ports 17 | - genish.js tutorial 18 | - What does the harmonic series sound like? 19 | - Thoughts on improving Web Audio 20 | - Talking Machines interview Doug Eck about Generative Art 21 | 22 | ##### [Web Audio Weekly 67](http://blog.chrislowis.co.uk//waw/2016/07/17/web-audio-weekly-67.html) : 2016-07-17 23 | - Djenerator: A metal breakdown generator 24 | - DX7 Emulator 25 | - 108 26 | - Space Bumps 27 | - Third International Conference on Technologies for Music Notation and Representation 28 | - StepSequencer 29 | - VisualizerMicro 30 | - Electronic Ladyland 31 | 32 | ##### [Web Audio Weekly 66](http://blog.chrislowis.co.uk//waw/2016/06/10/web-audio-weekly-66.html) : 2016-06-10 33 | - midi.city 34 | - Beat Detection Using JavaScript and the Web Audio API 35 | - Recreating Theremin With JS And Web Audio API 36 | - Loop Drop now free to download 37 | - Talks 38 | - The Great Outdoors 39 | - Efflux 40 | - Control Web Audio applications with Leap Motion 41 | - soundcompare 42 | - Web Audio API may allow additional cross-site tracking 43 | - ChiptuneBlaster 44 | - What If There Was A Dubstep Song But Instead Of The Drop There Was Just The Seinfeld Theme Song 45 | 46 | ##### [Web Audio Weekly 65](http://blog.chrislowis.co.uk//waw/2016/05/29/web-audio-weekly-64.html) : 2016-05-29 47 | - Audiograph 48 | - genish.js 49 | - Tiny 808 50 | - Theremin 51 | - Chrome Music Lab: Making Kandinski 52 | - Scribble Audio 53 | - Pixel Synth 54 | 55 | ##### [Web Audio Weekly 64](http://blog.chrislowis.co.uk//waw/2016/04/29/web-audio-weekly-64.html) : 2016-04-29 56 | - Jory Prum: 1975-2016 57 | - Novation use Web MIDI to bring Circuit to the web 58 | - mod-synth.io 59 | - Cracked 60 | - Mira 61 | - Envelope Generator 62 | - midi-ports: easy access to MIDI hardware 63 | - MIDI Logger - debugger console for MIDI 64 | - A curated list about Audio Visualisation 65 | - WKT Audio: Web Audio API file loader 66 | - Gregorian Voices: Early Roman Catholic Church Song Generator 67 | 68 | ##### [Web Audio Weekly 63](http://blog.chrislowis.co.uk//waw/2016/04/14/web-audio-weekly-63.html) : 2016-04-14 69 | - TweetFM 70 | - Soledad Penadés Peer to Peer screencast 71 | - Web Audio Conference 2016 72 | 73 | ##### [Web Audio Weekly 62](http://blog.chrislowis.co.uk//waw/2016/04/03/web-audio-weekly-62.html) : 2016-04-03 74 | - Tools for Thought: Graphical Algebra and Fourier Analysis 75 | - WAC 2016 76 | - Procedural game music in BlockShip Wars 77 | - MidiWriterJS 78 | - W3C online course on HTML5/Web Audio 79 | - Tascam Portastudio Simulation 80 | - 19 TET Keyboard 81 | - Tinyrave 82 | - Play Drums Online 83 | - Humpbacks synchronize their music across oceans, and there’s sheet music to prove it 84 | 85 | ##### [Web Audio Weekly 61](http://blog.chrislowis.co.uk//waw/2016/03/18/web-audio-weekly-61.html) : 2016-03-18 86 | - Chrome Music Lab 87 | - Eye Conductor Brings MIDI To People With Disabilities 88 | - Plan8 Throwerwall 89 | - Glitch: a noisy fusion of math and music 90 | - Clara Rockmore’s 105th Birthday 91 | - jsSID 92 | - WebGL and Web Audio = Fireworks 93 | 94 | ##### [Web Audio Weekly 60](http://blog.chrislowis.co.uk//waw/2016/03/04/web-audio-weekly-60.html) : 2016-03-04 95 | - Web Audio Arpeggiator 96 | - Klangmeister 97 | - In brief 98 | - MediaRecorder API implemented in Google Chrome 99 | - Stochastic Synthesis 100 | - flat.io 101 | - Angular 2 / TypeScript and Web Audio 102 | - Wintergatan Marble Machine 103 | 104 | ##### [Web Audio Weekly 59](http://blog.chrislowis.co.uk//waw/2016/02/26/web-audio-weekly-59.html) : 2016-02-26 105 | - Interview with Paul Adenot, Web Audio Spec Editor 106 | - Senior Ruby Developer at Samplephonics 107 | - Web Audio Updates in Chrome 49 108 | - Manta: a ClojureScript library for making music with the Web Audio API 109 | - Using Web Audio API to decode and play an MP3 file 110 | - Web Audio API snippets for Atom 111 | - Basic concepts behind Web Audio API 112 | - TonalHub: Listen to a Github project 113 | 114 | ##### [Web Audio Weekly 58](http://blog.chrislowis.co.uk//waw/2016/02/17/web-audio-weekly-58.html) : 2016-02-17 115 | - Playing Fasttracker 2 files in JavaScript 116 | - Web Audio BBQ Party in Barcelona 117 | - \* Using Web Audio API to decode and play an MP3 file 118 | - Glowsynth 119 | - \* An introduction to Web MIDI 120 | - \* Understanding AudioParams 121 | - Singular Value Decomposition: The Movie 122 | 123 | ##### [Web Audio Weekly 57](http://blog.chrislowis.co.uk//waw/2016/02/06/web-audio-weekly-57.html) : 2016-02-06 124 | - mmorph 125 | - Machine Learning for Musicians and Artists 126 | - Meyda 3.0.0 127 | - Yamaha Soundmondo: Web MIDI patch sharing app 128 | - Web Audio Conference 2016: early bird registration 129 | - Chrome 48 released - with Web Audio method chaining 130 | - Starting the Audio Context on user action (iOS) 131 | - Fourier Visualisations 132 | - Virtual Oscilloscope 133 | - Trump Donald 134 | 135 | ##### [Web Audio Weekly 56](http://blog.chrislowis.co.uk//waw/2016/01/29/web-audio-weekly-56.html) : 2016-01-29 136 | - Recreating the sound of night vision googles 137 | - Sampulator 138 | - Elements of Dance Music 139 | - Creating Virtual MIDI Ports On OSX for Web MIDI 140 | - Audio glitches with a terminal 141 | 142 | ##### [Web Audio Weekly 55](http://blog.chrislowis.co.uk//waw/2016/01/22/web-audio-weekly-55.html) : 2016-01-22 143 | - PolyRhythm: a poly-rhythm generator and visualiser 144 | - Web Audio, the ugly click and the human ear 145 | - Making a WebGL music video 146 | - Luden’s Beat Box 147 | - Should your web audio app have a limiter? 148 | - Pierre Boulez 149 | 150 | ##### [Web Audio Weekly 54](http://blog.chrislowis.co.uk//waw/2016/01/15/web-audio-weekly-54.html) : 2016-01-15 151 | - Canopy - a Web Audio scratch pad 152 | - Modulator: A Web Audio modular synthesiser 153 | - Matt McKegg: I play the JavaScript 154 | - Monophonic Ringtone Synthesiser 155 | - Little Drummer Toy 156 | - 5:1 Web Audio demo from Dolby 157 | - Making an interactive Web Audio slide-deck 158 | - Proper loudness metering on the web with EBU R128 159 | - Modern Approaches: Producers reveal their sound philosophies 160 | - Exploring the Web Audio API with D3 161 | - Dear Architects: Sound Matters 162 | 163 | ##### [Web Audio Weekly 53](http://blog.chrislowis.co.uk//waw/2015/12/13/web-audio-weekly-53.html) : 2015-12-13 164 | - Recreating phone sounds with Web Audio 165 | - The Indian Drone Instrument: Version 2 166 | - 2nd Annual Web Audio Conference - registration now open 167 | - Bringing your code to the streets 168 | - 2Decks: HTML5 DJ App 169 | - Jam3 Web Audio Gotchas 170 | - Creative Strategies for Electronic Music Producers 171 | - Open source effects pedal with Web Audio patch auditioning 172 | - Watch Daedelus compare the TR-808 and TR-8 173 | - Techno made entirely with physical, mechanical objects 174 | 175 | ##### [Web Audio Weekly 52](http://blog.chrislowis.co.uk//waw/2015/11/20/web-audio-weekly-52.html) : 2015-11-20 176 | - Piano Phase 177 | - Web MIDI Application Developer at Novation 178 | - Typatone 179 | - Web Audio Advent Calendar: Call for Contributions 180 | - Amplitude Modulation Synthesis 181 | - Web Audio Multiple Track Waveform Editor 182 | - Working with the Babylon.js Game Engine 183 | - Paul Adenot at jsconf.asia ‘15 184 | - Tracking with Ultrasound Beacons 185 | 186 | ##### [Web Audio Weekly 51](http://blog.chrislowis.co.uk//waw/2015/10/30/web-audio-weekly-51.html) : 2015-10-30 187 | - Hands on Web Audio 188 | - Looplabs 189 | - Web Audio JS Developer at Looplabs 190 | - pizzicato.js 191 | - Blend4Web adds Web Audio support 192 | - New node chaining API now in Firefox Nightly 193 | - Pitch shift the audio from any HTML5 video 194 | - Trent Reznor: Archetype of a Synthesizer 195 | 196 | ##### [Web Audio Weekly 50](http://blog.chrislowis.co.uk//waw/2015/10/24/web-audio-weekly-50.html) : 2015-10-24 197 | - midi.space 198 | - The Future of Web Audio 199 | - Farfisa Fast 3 Organ Simulator 200 | - Generative Jazz with Web Audio 201 | - Web MIDI wrapper library 202 | - The Art of Arrangement for Dynamic Music Systems in Games 203 | - TR-808 Cowbell and Hi-Hat recreation with Web Audio 204 | - 808: The Movie 205 | 206 | ##### [Web Audio Weekly 49](http://blog.chrislowis.co.uk//waw/2015/09/19/web-audio-weekly-49.html) : 2015-09-19 207 | - Sound Design in Web Audio 208 | - Senior Frontend Developer for IDAGIO 209 | - A Tale of no clocks 210 | - Visualising audio waveforms in polar coordinates 211 | - The Pentaphone 212 | - Virtual Audio Graph 213 | - iOS 9 Problems with Web Audio 214 | - Creating UIs for the Web Audio API 215 | - Find the invisible cow 216 | 217 | ##### [Web Audio Weekly 48](http://blog.chrislowis.co.uk//waw/2015/09/03/web-audio-weekly-48.html) : 2015-09-03 218 | - Creating an accessible breakout game 219 | - Kodo Games Web Audio Tutorial 220 | - Microtonal Web Synth 221 | - Online course: Audio Signal Processing for Music Applications 222 | - Cat Purr Noise Generator 223 | - Audio Sampling and the Delay Node 224 | - Dub Siren 225 | - Responsive Drum Machine 226 | - WebMIDI “now working” on Firefox 227 | - wOOfer-The Second Pie 228 | 229 | ##### [Web Audio Weekly 47](http://blog.chrislowis.co.uk//waw/2015/08/21/web-audio-weekly-47.html) : 2015-08-21 230 | - The Digital Surgeons Web Audio Meetup 231 | - Cole Willsea’s Web Audio Experiments 232 | - Flowkey 233 | - Web Audio NPM packages 234 | - My Web Audio Reading List 235 | - The Neuroscience of Drumming 236 | 237 | ##### [Web Audio Weekly 46](http://blog.chrislowis.co.uk//waw/2015/08/14/web-audio-weekly-46.html) : 2015-08-14 238 | - AudioKeys: a QWERTY keyboard for Web Audio projects 239 | - Learning and tutorials 240 | - Web Audio Meet-up in Lausanne, Switzerland 241 | - soundio: a standard way of creating music sequence data in JSON 242 | - This is Not a Machine Learning 243 | - Making a game: audio 244 | 245 | ##### [Web Audio Weekly 45](http://blog.chrislowis.co.uk//waw/2015/08/07/web-audio-weekly-45.html) : 2015-08-07 246 | - Introduction to Web Audio with Stuart Memo 247 | - Game of Reich 248 | - Web Audio Recorder Node 249 | - Machines learn to play Tabla 250 | - W3C Music Notation Community Group 251 | - 3D audio visualisations with three.js 252 | - Synthesisers 253 | 254 | ##### [Web Audio Weekly 44](http://blog.chrislowis.co.uk//waw/2015/07/24/web-audio-weekly-44.html) : 2015-07-24 255 | - Rain Today - your daily source of natural rain sounds 256 | - Submissions open for the 2nd International Web Audio Conference 257 | - Smooth Fading in Web Audio 258 | - Dynamic Sound with the Web Audio API in Microsoft Flight Simulator Arcade 259 | - Web Audio Basics 260 | - Web Audio API auto-complete package for Sublime Text 261 | - Social Media InterFace For Music 262 | - Angular Synthesiser 263 | - Mentored Firefox Web Audio Improvements 264 | - Artist seminar with Tyler Marenyi 265 | 266 | ##### [Web Audio Weekly 43](http://blog.chrislowis.co.uk//waw/2015/07/18/web-audio-weekly-43.html) : 2015-07-18 267 | - Viktor NV-1 Synthesiser 268 | - Learning how to read sheet music using the Web MIDI API 269 | - BeatSketch 270 | - Beautiful Audio Editor 271 | - Exploring the HTML5 Web Audio API: Filters 272 | - Keith McMillen: Making music in the browser 273 | - Inside Synthesis: FM Synthesis 274 | 275 | ##### [Web Audio Weekly 42](http://blog.chrislowis.co.uk//waw/2015/07/10/web-audio-weekly-42.html) : 2015-07-10 276 | - Building the Madeon Adventure Machine 277 | - Serial communication using Web Audio 278 | - Tone.js version 5 released 279 | - Web Audio Meetup in Philadelphia 280 | - MIDI file rendering in the browser 281 | - Solarbeat 282 | - Building a Realtime Music Sync Collaboration App With PubNub 283 | - Learning: Think DSP 284 | - How I’d Redesign Sheet Music 285 | 286 | ##### [Web Audio Weekly 41](http://blog.chrislowis.co.uk//waw/2015/06/26/web-audio-weekly-41.html) : 2015-06-26 287 | - Building a HTML5 Guitar Tuner 288 | - A brief history of synthesis with the Web Audio API 289 | - beet.js - a polyrhythmic sequencer library 290 | - Beat frequencies 291 | - Dynamic Sound with the Web Audio API 292 | - Reverb and reverb design: a history 293 | - 120years.net 294 | 295 | ##### [Web Audio Weekly 40](http://blog.chrislowis.co.uk//waw/2015/06/19/web-audio-weekly-40.html) : 2015-06-19 296 | - Loop Drop 297 | - Fields: An exploration into the use of mobile devices as a medium for sound diffusion 298 | - wavesurfer.js 299 | - LabSound 300 | - WebAssembly: A new binary format for the web 301 | - Kadenze: Free online music courses 302 | 303 | ##### [Web Audio Weekly 39](http://blog.chrislowis.co.uk//waw/2015/06/12/web-audio-weekly-39.html) : 2015-06-12 304 | - Recreating the Birdman opening credits with the Web Audio API 305 | - Web Audio premiere at the València Vox Festival 306 | - Music Visualisation with p5.js 307 | - The 2nd Web Audio Conference - Call for Submissions 308 | - Browser MIDI Is About Hardware As Much As Music 309 | - Learning the Web Audio API 310 | - Midem Hackday 311 | - A quick correction 312 | - The sound of dialup 313 | 314 | ##### [Web Audio Weekly 38](http://blog.chrislowis.co.uk//waw/2015/06/05/web-audio-weekly-38.html) : 2015-06-05 315 | - Karplus-Strong String Synthesis 316 | - Bringing Web Audio to Microsoft Edge 317 | - SoundCite 318 | - Fun with the Web Audio API 319 | - Keith McMillen make music in the browser 320 | - AudioDrop 321 | - Raspberry PI as a Synthesiser 322 | 323 | ##### [Web Audio Weekly 37](http://blog.chrislowis.co.uk//waw/2015/05/29/web-audio-weekly-37.html) : 2015-05-29 324 | - Jazz.Computer 325 | - Matt McKegg at CampJS 326 | - Learn Web Audio at the Web Audio School 327 | - Synthesising Drum Sounds with the Web Audio API 328 | - Practical Web Audio 329 | - Molgav 330 | - Juno 106 Emulator 331 | - Can I get an Amen? 332 | 333 | ##### [Web Audio Weekly 36](http://blog.chrislowis.co.uk//waw/2015/05/22/web-audio-weekly-36.html) : 2015-05-22 334 | - Typedrummer 335 | - Listen to Wikipedia edits 336 | - Web Audio API Developer Tools for Chrome 337 | - Web Audio Slack Channel 338 | - Scrolling Through Sound 339 | - Web MIDI API available in Chrome 43 Beta 340 | - The Audio Processing Dog House 341 | 342 | ##### [Web Audio Weekly 35](http://blog.chrislowis.co.uk//waw/2015/03/23/web-audio-weekly-35.html) : 2015-03-23 343 | - Making a boombap beat with dilla and the Web Audio API 344 | - Madeon’s Adventure Machine 345 | - Web MIDI spec update 346 | - Web Audio Charity Hack Day in Scotland 347 | - Vuvuzela Denoiser 348 | - 303 simulator 349 | - Hand-drawn schematics from the Bob Moog archive 350 | 351 | ##### [Web Audio Weekly 34](http://blog.chrislowis.co.uk//waw/2015/03/10/web-audio-weekly-34.html) : 2015-03-10 352 | - Motion sensing using the Doppler effect 353 | - A comprehensive scheduling tool for Web Audio 354 | - Audiocogs: Audio codecs for the web 355 | - Detour hiring OS X engineer in SF to build text-driven audio sequencer 356 | - Sonoport Sound Models 357 | - W3C Multi-device timing community group 358 | - Circles, Sines and Signals: A primer on DSP 359 | 360 | ##### [Web Audio Weekly 33](http://blog.chrislowis.co.uk//waw/2015/02/28/web-audio-weekly-33.html) : 2015-02-28 361 | - Web Audio Meetups in London and New York 362 | - Birdsongs, Musique Concrète, and the Web Audio API 363 | - What’s new in Web Audio in Firefox 37/38 364 | - Pentaphone 365 | - Web Looper 366 | - Babylon.js v2.0 367 | 368 | ##### [Web Audio Weekly 32](http://blog.chrislowis.co.uk//waw/2015/02/15/web-audio-weekly-32.html) : 2015-02-15 369 | - Google I/O 2015 Web Audio Demo 370 | - Web Audio API in Node.js 371 | - Videos from Web Audio Conf 372 | - Benchmarking FFT performance 373 | - AudioCrawl 374 | - Converse Rubber Tracks Sample Library 375 | 376 | ##### [Web Audio Weekly 31](http://blog.chrislowis.co.uk//waw/2015/02/06/web-audio-weekly-31.html) : 2015-02-06 377 | - An introduction to Web MIDI and Web Audio 378 | - Audio Visualisation with the Web Audio API 379 | - Experiments with DART and Web Audio 380 | - More highlights from the Web Audio Conference 381 | - Web Audio Developer Tools for Chrome 382 | - WebAudioSynth V2 383 | - Music Thing 384 | 385 | ##### [Web Audio Weekly 30](http://blog.chrislowis.co.uk//waw/2015/01/31/web-audio-weekly-30.html) : 2015-01-31 386 | - Timing and Scheduling 387 | - Audio Workers and custom DSP 388 | - Tools and Education 389 | - Performances 390 | - Finally - Hya-Wave released 391 | 392 | ##### [Web Audio Weekly 29](http://blog.chrislowis.co.uk//waw/2014/12/22/web-audio-weekly-29.html) : 2014-12-22 393 | - Web Audio and 3D Soundscapes 394 | - Web Audio Timing Tutorial 395 | - Tools for the 21st century musician 396 | - Visualisations of live radio streams 397 | - How To Draw Mushrooms On An Oscilloscope With Sound 398 | 399 | ##### [Web Audio Weekly 28](http://blog.chrislowis.co.uk//waw/2014/12/04/web-audio-weekly-28.html) : 2014-12-04 400 | - Time Stretching with Web Audio 401 | - Web Audio Editor 402 | - Using Fourier Transforms with the Web Audio API 403 | - How Speakers Make Sound 404 | - Mechanical Signal Analysis 405 | 406 | ##### [Web Audio Weekly 27](http://blog.chrislowis.co.uk//waw/2014/11/17/web-audio-weekly-27.html) : 2014-11-17 407 | - W3C Audio WG meets at TPAC 408 | - Meyda - audio feature extraction library 409 | - Headphone Surround Sound 410 | - Blip 411 | - Websynths 412 | 413 | ##### [Web Audio Weekly 26](http://blog.chrislowis.co.uk//waw/2014/09/22/web-audio-weekly-26.html) : 2014-09-22 414 | - Tone.js 415 | - True, A Web Audio Music Video 416 | - Web Audio Hackdays 417 | - Leon Theremin - CIA Nemesis 418 | 419 | ##### [Web Audio Weekly 25](http://blog.chrislowis.co.uk//waw/2014/09/07/web-audio-weekly-25.html) : 2014-09-07 420 | - 1st Web Audio Conference submission deadline 421 | - Oscilloscope 422 | - Web Audio synthesizer by Luke Teaford 423 | - Web Audio Mock 424 | - NASA Scientists listen to data 425 | - Bob Moog Foundation pays tribute to Leon Theremin 426 | 427 | ##### [Web Audio Weekly 24](http://blog.chrislowis.co.uk//waw/2014/08/16/web-audio-weekly-24.html) : 2014-08-16 428 | - I dropped my phone the screen cracked 429 | - Plans to improve scriptProcessorNode 430 | - Calculating BPM using Javascript and the Spotify Web API 431 | - p5.js 432 | - The art of the loop 433 | 434 | ##### [Web Audio Weekly 23](http://blog.chrislowis.co.uk//waw/2014/08/07/web-audio-weekly-23.html) : 2014-08-07 435 | - Beat Detection Using JavaScript and the Web Audio API 436 | - Web Audio Hackday 437 | - jsaSound 438 | - Audio Sort 439 | - Qwerty Hancock 440 | - Extracting audio from visual information 441 | 442 | ##### [Web Audio Weekly 22](http://blog.chrislowis.co.uk//waw/2014/07/29/web-audio-weekly-22.html) : 2014-07-29 443 | - Web Audio API changes in Chrome 36 444 | - Dub delay effects with the Web Audio API 445 | - Integration of Web Audio with WebRTC 446 | - Serving up files for the Web Audio API 447 | - Nexus UI 448 | - SuperCollider is easy and so can you! 449 | 450 | ##### [Web Audio Weekly 21](http://blog.chrislowis.co.uk//waw/2014/07/20/web-audio-weekly-21.html) : 2014-07-20 451 | - Flora Drift 452 | - Jerusalem 453 | - How to Build a Supersaw Synthesizer 454 | - Coursera Course on Digital Sound Design 455 | - Tuna Knobs 456 | 457 | ##### [Web Audio Weekly 20](http://blog.chrislowis.co.uk//waw/2014/07/03/web-audio-weekly-20.html) : 2014-07-03 458 | - Wavepot 459 | - Web Audio Editor in Firefox 460 | - Faust announces Web Audio support 461 | - Making Music Mobile with the Web (Google I/O) 462 | - Interactive timeline of synthesis 463 | 464 | ##### [Web Audio Weekly 19](http://blog.chrislowis.co.uk//waw/2014/06/14/web-audio-weekly-19.html) : 2014-06-14 465 | - 1st Web Audio Conference 466 | - CoffeeCollider 467 | - Tango Music Visualisations 468 | - Compress audio buffers with libvorbis.js and lago 469 | - beeplay.js 470 | - The greatest electronic albums of the 1950s and 1960s 471 | 472 | ##### [Web Audio Weekly 18](http://blog.chrislowis.co.uk//waw/2014/05/30/web-audio-weekly-18.html) : 2014-05-30 473 | - Web Audio API coming to Internet Explorer 474 | - Chrome Cube Lab 475 | - An interview with Adrian Holovaty of Soundslice 476 | - Sophisticated Analogue Synth in Soundtrap 477 | - BHUMP : an HTML5 Multitrack player 478 | - Laurie Spiegel plays the Alles synth 479 | 480 | ##### [Web Audio Weekly 17](http://blog.chrislowis.co.uk//waw/2014/05/16/web-audio-weekly-17.html) : 2014-05-16 481 | - Improve the Web Audio API by writing tests 482 | - Web Audio Editor in Firefox 483 | - Visualising Audio with the Web Audio API 484 | - Designing Godzilla’s Scream 485 | - The New York School of Synthesis 486 | 487 | ##### [Web Audio Weekly 16](http://blog.chrislowis.co.uk//waw/2014/05/16/web-audio-weekly-16.html) : 2014-05-16 488 | - Bandhub 489 | - Theresa’s Sound World 490 | - ChucK demos 491 | - Fields 492 | - Two ways to see sound 493 | 494 | ##### [Web Audio Weekly 15](http://blog.chrislowis.co.uk//waw/2014/04/27/web-audio-weekly-15.html) : 2014-04-27 495 | - Building a collaborative music production environment 496 | - Mixhub 497 | - Lissajous 498 | - Shoreditch Experimental Music School (1969) 499 | - BBC Outriders: World of Sound 500 | 501 | ##### [Web Audio Weekly 14](http://blog.chrislowis.co.uk//waw/2014/04/15/web-audio-weekly-14.html) : 2014-04-15 502 | - Echo 503 | - Patatap 504 | - Bitcrushing 505 | - Retro game music 506 | - Beat It 507 | 508 | ##### [Web Audio Weekly 13](http://blog.chrislowis.co.uk//waw/2014/04/03/web-audio-weekly-13.html) : 2014-04-03 509 | - Soundslice 510 | - Connecting external devices to smartphones using Web Audio 511 | - MIDI HACK 512 | - Listen to sorting algorithms 513 | - The drum machine that changed music 514 | 515 | ##### [Web Audio Weekly 12](http://blog.chrislowis.co.uk//waw/2014/03/25/web-audio-weekly-12.html) : 2014-03-25 516 | - Visualising birdsong with Web Audio 517 | - Making charts accessible using the Web Audio API 518 | - Audio Tags: Web Components + Web Audio 519 | - Generative music with graphs 520 | - “like jQuery for your ears” 521 | - Steve Reich: “Don’t tell me you don’t have the right equipment” 522 | 523 | ##### [Web Audio Weekly 11](http://blog.chrislowis.co.uk//waw/2014/03/16/web-audio-weekly-11.html) : 2014-03-16 524 | - Web Audio supports live performance by LCO and Jonny Greenwood 525 | - JSnode 526 | - music.js 527 | - Making car sounds with web audio synthesis 528 | - Roland announces successor to TR-808 529 | 530 | ##### [Web Audio Weekly 10](http://blog.chrislowis.co.uk//waw/2014/03/06/web-audio-weekly-10.html) : 2014-03-06 531 | - hya.io: A graph-based audio workstation 532 | - webAudioContext –> AudioContext in Chrome 533 | - WebAudiox.js 534 | - A little tip about AudioContext.currentTime 535 | - Read O’Reilly’s Web Audio API book for free 536 | - “Biscuit tins made of sound” 537 | 538 | ##### [Web Audio Weekly 9](http://blog.chrislowis.co.uk//waw/2014/02/27/web-audio-weekly-9.html) : 2014-02-27 539 | - A collection of Web Audio components built with d3.js 540 | - Exploring the JP-8000 Supersaw 541 | - Recreation of Commodore 64 sounds 542 | - Paul Adenot talks about Web Audio at FOSDEM 543 | - Touch enabled Web Audio theremin 544 | - Synth Britannia - the history of the synthesiser 545 | 546 | ##### [Web Audio Weekly 8](http://blog.chrislowis.co.uk//waw/2014/02/07/web-audio-weekly-8.html) : 2014-02-07 547 | - Granular Synthesiser 548 | - The Viability of the Web Browser as a Computer Music Platform 549 | - WebkitGTK enables Web Audio 550 | - A brief history of sampling 551 | - Programming analog synthesizers 552 | 553 | ##### [Web Audio Weekly 7](http://blog.chrislowis.co.uk//waw/2014/01/23/web-audio-weekly-7.html) : 2014-01-23 554 | - Recreating THX’s Deep Note in JavaScript with the Web Audio API 555 | - RSA Key Extraction via Low-Bandwidth Acoustic Cryptanalysis 556 | - Pitch detection 557 | - Metamath Music 558 | 559 | ##### [Web Audio Weekly 6](http://blog.chrislowis.co.uk//waw/2013/12/16/web-audio-weekly-6.html) : 2013-12-16 560 | - Make your browser dance 561 | - Octahedrone 562 | - Listen Up! Binaural Sound 563 | - Everything You Need to Know About playbackRate 564 | - LiveCamp 565 | - Algorithmic Music subreddit 566 | 567 | ##### [Web Audio Weekly 5](http://blog.chrislowis.co.uk//waw/2013/12/01/web-audio-weekly-5.html) : 2013-12-01 568 | - Word Problems 569 | - Audio Tags: Web Components + Web Audio 570 | - This Exquisite Music Engine 571 | - Peaks.js 572 | - Instant Audio Processing Book 573 | 574 | ##### [Web Audio Weekly 4](http://blog.chrislowis.co.uk//waw/2013/11/18/web-audio-weekly-4.html) : 2013-11-18 575 | - Soundtrap 576 | - Audio sprites 577 | - TrueGrid 578 | - Musical Chess 579 | 580 | ##### [Web Audio Weekly 3](http://blog.chrislowis.co.uk//waw/2013/11/10/web-audio-weekly-3.html) : 2013-11-10 581 | - MixBolt - Web Audio Turntables 582 | - SuperCollider-inspired live coding environments 583 | - Programming for Musicians 584 | - Understanding the FFT 585 | - Build a real synth 586 | 587 | ##### [Web Audio Weekly 2](http://blog.chrislowis.co.uk//waw/2013/11/04/web-audio-weekly-2.html) : 2013-11-04 588 | - Firefox 25 released 589 | - Steller - a framework for composeable sound modules 590 | - Novation/Focusrite working on cross-platform Web MIDI software 591 | - Listen to Conway’s Game of Life 592 | - Train Your Ears 593 | 594 | ##### [Web Audio Weekly 1](http://blog.chrislowis.co.uk//waw/2013/10/27/web-audio-weekly-1.html) : 2013-10-27 595 | - Looping 596 | - Web MIDI synthesiser 597 | - Custom-shaped Online Noise Machines 598 | - Building a Synthesizer with the Web Audio API 599 | -------------------------------------------------------------------------------- /links/index-of-web-audio-weekly/make.rb: -------------------------------------------------------------------------------- 1 | require 'open-uri' 2 | require 'nokogiri' 3 | 4 | def read_local_issues 5 | header = /^##### \[(.+)\]\((.+)\) : (.+)$/ 6 | issues = [] 7 | issue = nil 8 | 9 | text = open("#{ __dir__ }/README.md").read rescue '' 10 | 11 | text.each_line do |line| 12 | case 13 | when header =~ line 14 | issues << issue unless issue.nil? 15 | issue = { title:$1, url:$2, date:$3, topics:[] } 16 | when (issue and line.start_with?('-')) 17 | issue[:topics] << line.chomp 18 | end 19 | end 20 | 21 | issues << issue unless issue.nil? 22 | 23 | issues 24 | end 25 | 26 | def fetch_published_issues 27 | base_url = 'http://blog.chrislowis.co.uk/' 28 | 29 | html = open(base_url + 'waw.html').read 30 | doc = Nokogiri::HTML.parse(html, nil, 'utf-8') 31 | 32 | doc.css('.listing > li').map {|li| 33 | title = li.css('a')[0].text 34 | url = base_url + li.css('a')[0][:href] 35 | date = Date.parse(li.css('span')[0].text).strftime('%Y-%m-%d') 36 | { title:title, url:url, date:date, topics:[] } 37 | } 38 | end 39 | 40 | def merge_issues(a, b) 41 | a = Hash[a.map {|issue| [ issue[:url], issue ] }] 42 | b = Hash[b.map {|issue| [ issue[:url], issue ] }] 43 | 44 | b.merge(a).values.sort_by {|issue| issue[:url] }.reverse 45 | end 46 | 47 | def fetch_topics(url) 48 | html = open(url).read 49 | doc = Nokogiri::HTML.parse(html, nil, 'utf-8') 50 | 51 | doc.css('h2').map {|h2| '- ' + escape_markdown(h2.text) } 52 | end 53 | 54 | def escape_markdown(text) 55 | text = text.gsub('*', '\*') 56 | text 57 | end 58 | 59 | def main(header) 60 | issues = merge_issues(read_local_issues, fetch_published_issues) 61 | 62 | issues.select {|issue| issue[:topics].empty? }.each_with_index do |issue, index| 63 | sleep(2) unless index.zero? 64 | puts "fetch: #{ issue[:url] }" 65 | issue[:topics] = fetch_topics(issue[:url]) 66 | end 67 | 68 | num_of_posts = issues.length 69 | num_of_topics = issues.reduce(0) {|sum, issue| sum + issue[:topics].length } 70 | 71 | open("#{ __dir__ }/README.md", "w") do |f| 72 | f.puts header 73 | f.puts 74 | f.puts ":trophy: _#{ num_of_posts } posts and #{ num_of_topics } topics are... awesome!!_" 75 | f.puts 76 | f.puts '---' 77 | issues.each do |issue| 78 | title, url, date, topics = issue.values_at(:title, :url, :date, :topics) 79 | f.puts 80 | f.puts "##### [#{ title }](#{ url }) : #{ date }" 81 | f.puts topics.join("\n") 82 | end 83 | end 84 | 85 | puts 'done!!' 86 | end 87 | 88 | main <<-EOS 89 | # Index of Web Audio Weekly 90 | 91 | Web Audio Weekly is a valuable source of the latest topics about the Web Audio API, the Web MIDI API or sound on the web that written by Chris Lowis. 92 | 93 | http://blog.chrislowis.co.uk/waw.html 94 | EOS 95 | -------------------------------------------------------------------------------- /links/music-programming-languages.md: -------------------------------------------------------------------------------- 1 | # Music Programming Languages 2 | 3 | ## Open Source 4 | 5 | #### [SuperCollider](http://supercollider.github.io/) 6 | SuperCollider is a programming language for real time audio synthesis and algorithmic composition. 7 | 8 | #### [Overtone](http://overtone.github.io/) 9 | Collaborative Programmable Music 10 | 11 | #### [Sonic PI](http://sonic-pi.net/) 12 | The Live Coding Synth for Everyone 13 | 14 | #### [Pure Data](https://puredata.info/) 15 | Real-time graphical dataflow programming environment for audio, video, and graphical processing. 16 | 17 | #### [Csound](http://csound.github.io/) 18 | A sound and music computing system 19 | 20 | ## Proprietary 21 | 22 | #### [Max/MSP](https://cycling74.com/products/max/) 23 | Max is a visual programming language for media. 24 | 25 | #### [Reaktor](http://www.native-instruments.com/en/products/komplete/synths/reaktor-6/) 26 | 27 | ## Others 28 | 29 | - [List of audio programming languages](https://en.wikipedia.org/wiki/List_of_audio_programming_languages) 30 | -------------------------------------------------------------------------------- /links/source-code-of-web-audio-api.md: -------------------------------------------------------------------------------- 1 | # Source Code of Web Audio API 2 | 3 | ## Blink 4 | 5 | https://chromium.googlesource.com/chromium/blink/ 6 | 7 | - https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/ 8 | - https://chromium.googlesource.com/chromium/blink/+/master/Source/platform/audio/ 9 | 10 | ## WebKit 11 | 12 | https://trac.webkit.org/browser/ 13 | 14 | - https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio 15 | - https://trac.webkit.org/browser/trunk/Source/WebCore/platform/audio 16 | 17 | ## Mozilla 18 | 19 | https://hg.mozilla.org/mozilla-central/ 20 | 21 | - https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio 22 | - https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/blink 23 | -------------------------------------------------------------------------------- /links/specification.md: -------------------------------------------------------------------------------- 1 | # Specification 2 | 3 | - [Web Audio API][1] 4 | - [Web Audio API - Editor's Draft][2] 5 | - [Web Audio API - Web APIs | MDN][3] 6 | - [Web Audio - Microsoft Developer Network][4] 7 | 8 | ## 日本語 9 | 10 | - [Web Audio API (日本語訳)][5] 11 | 12 | [1]:https://www.w3.org/TR/webaudio/ 13 | [2]:https://webaudio.github.io/web-audio-api/ 14 | [3]:https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API 15 | [4]:https://msdn.microsoft.com/en-us/library/dn985708(v=vs.85).aspx 16 | 17 | [5]:http://g200kg.github.io/web-audio-api-ja/ 18 | -------------------------------------------------------------------------------- /links/tutorials.md: -------------------------------------------------------------------------------- 1 | # Tutorials 2 | 3 | - [Getting Started with Web Audio API](http://www.html5rocks.com/en/tutorials/webaudio/intro/) 4 | - [Developing Game Audio with the Web Audio API](http://www.html5rocks.com/en/tutorials/webaudio/games/) 5 | - [A Tale of Two Clocks - Scheduling Web Audio with Precision](http://www.html5rocks.com/en/tutorials/audio/scheduling/) 6 | 7 | ## 日本語版 8 | 9 | - [Web Audio API の基礎](http://www.html5rocks.com/ja/tutorials/webaudio/intro/) 10 | - [Web Audio API を使用したゲーム用音声の開発](http://www.html5rocks.com/ja/tutorials/webaudio/games/) 11 | - [2 つの時計のお話 - Web Audio の正確なスケジューリングについて](http://www.html5rocks.com/ja/tutorials/audio/scheduling/) 12 | - [Web Audio API 解説 - 01.前説 | g200kg Music & Software](http://www.g200kg.com/jp/docs/webaudio/) 13 | -------------------------------------------------------------------------------- /node/CompareEqualToNode/README.md: -------------------------------------------------------------------------------- 1 | # CompareEqualToNode 2 | 3 | ### Expression 4 | 5 | `x = (a == b) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/CompareEqualToNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/CompareEqualToNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/CompareEqualToNode/ 15 | -------------------------------------------------------------------------------- /node/CompareEqualToNode/createCompareEqualToNode.js: -------------------------------------------------------------------------------- 1 | window.createCompareEqualToNode = (function() { 2 | "use strict"; 3 | 4 | function createCompareEqualToNode(context, a, b) { 5 | var c = createMathSubtractNode(context, a, b); 6 | 7 | return createIsZeroNode(context, c); 8 | } 9 | 10 | return createCompareEqualToNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/CompareEqualToNode/img/CompareEqualToNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareEqualToNode/img/CompareEqualToNode.png -------------------------------------------------------------------------------- /node/CompareEqualToNode/img/CompareEqualToNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareEqualToNode/img/CompareEqualToNodePlot.png -------------------------------------------------------------------------------- /node/CompareEqualToNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CompareEqualToNode 6 | 7 | 8 | 9 |

CompareEqualToNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /node/CompareGreaterThanNode/README.md: -------------------------------------------------------------------------------- 1 | # CompareGreaterThanNode 2 | 3 | ### Expression 4 | 5 | `x = (a > b) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/CompareGreaterThanNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/CompareGreaterThanNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/CompareGreaterThanNode/ 15 | -------------------------------------------------------------------------------- /node/CompareGreaterThanNode/createCompareGreaterThanNode.js: -------------------------------------------------------------------------------- 1 | window.createCompareGreaterThanNode = (function() { 2 | "use strict"; 3 | 4 | function createCompareGreaterThanNode(context, a, b) { 5 | var c = createMathSubtractNode(context, a, b); 6 | 7 | return createIsPositiveNode(context, c); 8 | } 9 | 10 | return createCompareGreaterThanNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/CompareGreaterThanNode/img/CompareGreaterThanNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareGreaterThanNode/img/CompareGreaterThanNode.png -------------------------------------------------------------------------------- /node/CompareGreaterThanNode/img/CompareGreaterThanNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareGreaterThanNode/img/CompareGreaterThanNodePlot.png -------------------------------------------------------------------------------- /node/CompareGreaterThanNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CompareGreaterThanNode 6 | 7 | 8 | 9 |

CompareGreaterThanNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /node/CompareGreaterThanOrEqualToNode/README.md: -------------------------------------------------------------------------------- 1 | # CompareGreaterThanOrEqualToNode 2 | 3 | ### Expression 4 | 5 | `x = (a >= b) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/CompareGreaterThanOrEqualToNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/CompareGreaterThanOrEqualToNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/CompareGreaterThanOrEqualToNode/ 15 | -------------------------------------------------------------------------------- /node/CompareGreaterThanOrEqualToNode/createCompareGreaterThanOrEqualToNode.js: -------------------------------------------------------------------------------- 1 | window.createCompareGreaterThanOrEqualToNode = (function() { 2 | "use strict"; 3 | 4 | function createCompareGreaterThanOrEqualToNode(context, a, b) { 5 | var c = createMathSubtractNode(context, a, b); 6 | 7 | return createIsPositiveOrZeroNode(context, c); 8 | } 9 | 10 | return createCompareGreaterThanOrEqualToNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/CompareGreaterThanOrEqualToNode/img/CompareGreaterThanOrEqualToNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareGreaterThanOrEqualToNode/img/CompareGreaterThanOrEqualToNode.png -------------------------------------------------------------------------------- /node/CompareGreaterThanOrEqualToNode/img/CompareGreaterThanOrEqualToNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareGreaterThanOrEqualToNode/img/CompareGreaterThanOrEqualToNodePlot.png -------------------------------------------------------------------------------- /node/CompareGreaterThanOrEqualToNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CompareGreaterThanOrEqualToNode 6 | 7 | 8 | 9 |

CompareGreaterThanOrEqualToNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /node/CompareLessThanNode/README.md: -------------------------------------------------------------------------------- 1 | # CompareLessThanNode 2 | 3 | ### Expression 4 | 5 | `x = (a < b) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/CompareLessThanNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/CompareLessThanNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/CompareLessThanNode/ 15 | -------------------------------------------------------------------------------- /node/CompareLessThanNode/createCompareLessThanNode.js: -------------------------------------------------------------------------------- 1 | window.createCompareLessThanNode = (function() { 2 | "use strict"; 3 | 4 | function createCompareLessThanNode(context, a, b) { 5 | var c = createMathSubtractNode(context, b, a); 6 | 7 | return createIsPositiveNode(context, c); 8 | } 9 | 10 | return createCompareLessThanNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/CompareLessThanNode/img/CompareLessThanNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareLessThanNode/img/CompareLessThanNode.png -------------------------------------------------------------------------------- /node/CompareLessThanNode/img/CompareLessThanNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareLessThanNode/img/CompareLessThanNodePlot.png -------------------------------------------------------------------------------- /node/CompareLessThanNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CompareLessThanNode 6 | 7 | 8 | 9 |

CompareLessThanNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /node/CompareLessThanOrEqualToNode/README.md: -------------------------------------------------------------------------------- 1 | # CompareLessThanOrEqualToNode 2 | 3 | ### Expression 4 | 5 | `x = (a <= b) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/CompareLessThanOrEqualToNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/CompareLessThanOrEqualToNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/CompareLessThanOrEqualToNode/ 15 | -------------------------------------------------------------------------------- /node/CompareLessThanOrEqualToNode/createCompareLessThanOrEqualToNode.js: -------------------------------------------------------------------------------- 1 | window.createCompareLessThanOrEqualToNode = (function() { 2 | "use strict"; 3 | 4 | function createCompareLessThanOrEqualToNode(context, a, b) { 5 | var c = createMathSubtractNode(context, b, a); 6 | 7 | return createIsPositiveOrZeroNode(context, c); 8 | } 9 | 10 | return createCompareLessThanOrEqualToNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/CompareLessThanOrEqualToNode/img/CompareLessThanOrEqualToNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareLessThanOrEqualToNode/img/CompareLessThanOrEqualToNode.png -------------------------------------------------------------------------------- /node/CompareLessThanOrEqualToNode/img/CompareLessThanOrEqualToNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareLessThanOrEqualToNode/img/CompareLessThanOrEqualToNodePlot.png -------------------------------------------------------------------------------- /node/CompareLessThanOrEqualToNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CompareLessThanOrEqualToNode 6 | 7 | 8 | 9 |

CompareLessThanOrEqualToNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /node/CompareNotEqualToNode/README.md: -------------------------------------------------------------------------------- 1 | # CompareNotEqualToNode 2 | 3 | ### Expression 4 | 5 | `x = (a != b) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/CompareNotEqualToNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/CompareNotEqualToNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/CompareNotEqualToNode/ 15 | -------------------------------------------------------------------------------- /node/CompareNotEqualToNode/createCompareNotEqualToNode.js: -------------------------------------------------------------------------------- 1 | window.createCompareNotEqualToNode = (function() { 2 | "use strict"; 3 | 4 | function createCompareNotEqualToNode(context, a, b) { 5 | var c = createMathSubtractNode(context, a, b); 6 | 7 | return createIsNotZeroNode(context, c); 8 | } 9 | 10 | return createCompareNotEqualToNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/CompareNotEqualToNode/img/CompareNotEqualToNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareNotEqualToNode/img/CompareNotEqualToNode.png -------------------------------------------------------------------------------- /node/CompareNotEqualToNode/img/CompareNotEqualToNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CompareNotEqualToNode/img/CompareNotEqualToNodePlot.png -------------------------------------------------------------------------------- /node/CompareNotEqualToNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CompareNotEqualToNode 6 | 7 | 8 | 9 |

CompareNotEqualToNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /node/CrossFadeNode/CrossFadeNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws1 = (x + 1) * 0.5 8 | ws2 = 1 - ws1 9 | 10 | plt.subplot(211) 11 | plt.title("ws1") 12 | plt.xlim(-1, 1) 13 | plt.ylim(-1.2, +1.2) 14 | plt.grid() 15 | plt.plot(x, ws1) 16 | 17 | plt.subplot(212) 18 | plt.title("ws2") 19 | plt.xlim(-1, 1) 20 | plt.ylim(-1.2, +1.2) 21 | plt.grid() 22 | plt.plot(x, ws2) 23 | 24 | plt.savefig("%s/img/CrossFadeNodeWaveShape.png" % os.path.dirname(__file__)) 25 | -------------------------------------------------------------------------------- /node/CrossFadeNode/README.md: -------------------------------------------------------------------------------- 1 | # CrossFadeNode 2 | 3 | ### Expression 4 | 5 | `x = a * ((c + 1) * 0.5) + b * (1 - ((c + 1) * 0.5))` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/CrossFadeNode.png) 10 | 11 | ### WaveShape 12 | 13 | - `ws1 = (x) -> (x + 1) * 0.5` 14 | - `ws2 = (x) -> 1 - ((x + 1) * 0.5)` 15 | 16 | ![](img/CrossFadeNodeWaveShape.png) 17 | 18 | ### Plot 19 | 20 | ![](img/CrossFadeNodePlot.png) 21 | http://mohayonao.github.io/waa-lab/node/CrossFadeNode/ 22 | -------------------------------------------------------------------------------- /node/CrossFadeNode/createCrossFadeNode.js: -------------------------------------------------------------------------------- 1 | window.createCrossFadeNode = (function() { 2 | "use strict"; 3 | 4 | var ws1 = createSelectAShaperCurve(8192); 5 | var ws2 = createSelectBShaperCurve(8192); 6 | 7 | function createCrossFadeNode(context, a, b, c) { 8 | var a0 = createWaveShaperNode(context, ws1, c); 9 | var b0 = createWaveShaperNode(context, ws2, c); 10 | var a1 = createMathMultiplyNode(context, a, a0); 11 | var b1 = createMathMultiplyNode(context, b, b0); 12 | 13 | return createMathAddNode(context, a1, b1); 14 | } 15 | 16 | function createSelectAShaperCurve(length) { 17 | var curve = new Float32Array(length); 18 | 19 | for (var i = 0; i < length; i++) { 20 | var x = (i / length) * 2 - 1; 21 | 22 | curve[i] = (x + 1) * 0.5; 23 | } 24 | 25 | return curve; 26 | } 27 | 28 | function createSelectBShaperCurve(length) { 29 | var curve = new Float32Array(length); 30 | 31 | for (var i = 0; i < length; i++) { 32 | var x = (i / length) * 2 - 1; 33 | 34 | curve[i] = 1 - ((x + 1) * 0.5); 35 | } 36 | 37 | return curve; 38 | } 39 | 40 | function createWaveShaperNode(context, curve, a) { 41 | var b = context.createWaveShaper(); 42 | 43 | b.curve = curve; 44 | 45 | a.connect(b); 46 | 47 | return b; 48 | } 49 | 50 | return createCrossFadeNode; 51 | })(); 52 | -------------------------------------------------------------------------------- /node/CrossFadeNode/img/CrossFadeNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CrossFadeNode/img/CrossFadeNode.png -------------------------------------------------------------------------------- /node/CrossFadeNode/img/CrossFadeNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CrossFadeNode/img/CrossFadeNodePlot.png -------------------------------------------------------------------------------- /node/CrossFadeNode/img/CrossFadeNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/CrossFadeNode/img/CrossFadeNodeWaveShape.png -------------------------------------------------------------------------------- /node/CrossFadeNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CrossFadeNode 6 | 7 | 8 | 9 |

CrossFadeNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /node/IsNegativeNode/IsNegativeNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws = np.zeros_like(x) 8 | ws[x < 0] = 1 9 | 10 | plt.subplot(111) 11 | plt.title("ws") 12 | plt.grid() 13 | plt.xlim(-1, 1) 14 | plt.ylim(-1.2, +1.2) 15 | plt.plot(x, ws) 16 | 17 | plt.savefig("%s/img/IsNegativeNodeWaveShape.png" % os.path.dirname(__file__)) 18 | -------------------------------------------------------------------------------- /node/IsNegativeNode/README.md: -------------------------------------------------------------------------------- 1 | # IsNegativeNode 2 | 3 | ### Expression 4 | 5 | `x = (a < 0) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/IsNegativeNode.png) 10 | 11 | ### WaveShape 12 | 13 | `ws = (x) -> (x < 0) ? 1 : 0` 14 | 15 | ![](img/IsNegativeNodeWaveShape.png) 16 | 17 | ### Plot 18 | 19 | ![](img/IsNegativeNodePlot.png) 20 | http://mohayonao.github.io/waa-lab/node/IsNegativeNode/ 21 | -------------------------------------------------------------------------------- /node/IsNegativeNode/createIsNegativeNode.js: -------------------------------------------------------------------------------- 1 | window.createIsNegativeNode = (function() { 2 | "use strict"; 3 | 4 | var EPSILON = 1e-4; 5 | var ws = createIsNegativeShaperCurve(65536); 6 | 7 | function createIsNegativeNode(context, a) { 8 | return createWaveShaperNode(context, ws, a); 9 | } 10 | 11 | function createIsNegativeShaperCurve(length) { 12 | var curve = new Float32Array(length); 13 | 14 | for (var i = 0; i < length; i++) { 15 | var x = (i / length) * 2 - 1; 16 | 17 | curve[i] = x < -EPSILON ? 1 : 0; 18 | } 19 | 20 | return curve; 21 | } 22 | 23 | function createWaveShaperNode(context, curve, a) { 24 | var b = context.createWaveShaper(); 25 | 26 | b.curve = curve; 27 | 28 | a.connect(b); 29 | 30 | return b; 31 | } 32 | 33 | return createIsNegativeNode; 34 | })(); 35 | -------------------------------------------------------------------------------- /node/IsNegativeNode/img/IsNegativeNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsNegativeNode/img/IsNegativeNode.png -------------------------------------------------------------------------------- /node/IsNegativeNode/img/IsNegativeNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsNegativeNode/img/IsNegativeNodePlot.png -------------------------------------------------------------------------------- /node/IsNegativeNode/img/IsNegativeNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsNegativeNode/img/IsNegativeNodeWaveShape.png -------------------------------------------------------------------------------- /node/IsNegativeNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IsNegativeNode 6 | 7 | 8 | 9 |

IsNegativeNode

10 | 11 | 12 | 13 | 14 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /node/IsNotZeroNode/IsNotZeroNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws1 = np.zeros_like(x) 8 | ws2 = np.zeros_like(x) 9 | 10 | ws1[:] = 1 11 | ws1[np.abs(x) < 1e-4] = 0 12 | 13 | ws2[x > 0.01] = 1 14 | 15 | plt.subplot(211) 16 | plt.title("ws1") 17 | plt.grid() 18 | plt.xlim(-1, 1) 19 | plt.ylim(-1.2, +1.2) 20 | plt.plot(x, ws1) 21 | 22 | plt.subplot(212) 23 | plt.title("ws2") 24 | plt.grid() 25 | plt.xlim(-1, 1) 26 | plt.ylim(-1.2, +1.2) 27 | plt.plot(x, ws2) 28 | 29 | plt.savefig("%s/img/IsNotZeroNodeWaveShape.png" % os.path.dirname(__file__)) 30 | -------------------------------------------------------------------------------- /node/IsNotZeroNode/README.md: -------------------------------------------------------------------------------- 1 | # IsNotZeroNode 2 | 3 | ### Expression 4 | 5 | `x = (a != 0) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/IsNotZeroNode.png) 10 | 11 | ### WaveShape 12 | 13 | `ws1 = (x) -> (x != 0) ? 1 : 0` 14 | 15 | _ws2 is used to provide stability the output._ 16 | 17 | ![](img/IsNotZeroNodeWaveShape.png) 18 | 19 | ### Plot 20 | 21 | ![](img/IsNotZeroNodePlot.png) 22 | http://mohayonao.github.io/waa-lab/node/IsNotZeroNode/ 23 | -------------------------------------------------------------------------------- /node/IsNotZeroNode/createIsNotZeroNode.js: -------------------------------------------------------------------------------- 1 | window.createIsNotZeroNode = (function() { 2 | "use strict"; 3 | 4 | var EPSILON = 1e-4; 5 | var ws1 = createIsNotZeroShaperCurve(65536); 6 | var ws2 = createFixedCurve(2048); 7 | 8 | function createIsNotZeroNode(context, a) { 9 | var b = createWaveShaperNode(context, ws1, a); 10 | 11 | return createWaveShaperNode(context, ws2, b); 12 | } 13 | 14 | function createIsNotZeroShaperCurve(length) { 15 | var curve = new Float32Array(length); 16 | 17 | for (var i = 0; i < length; i++) { 18 | var x = (i / length) * 2 - 1; 19 | 20 | curve[i] = Math.abs(x) <= EPSILON ? 0 : 1; 21 | } 22 | 23 | return curve; 24 | } 25 | 26 | function createFixedCurve(length) { 27 | var curve = new Float32Array(length); 28 | 29 | for (var i = 0; i < length; i++) { 30 | var x = (i / length) * 2 - 1; 31 | 32 | curve[i] = x > 0.01 ? +1 : 0; 33 | } 34 | 35 | return curve; 36 | } 37 | 38 | function createWaveShaperNode(context, curve, a) { 39 | var b = context.createWaveShaper(); 40 | 41 | b.curve = curve; 42 | 43 | a.connect(b); 44 | 45 | return b; 46 | } 47 | 48 | return createIsNotZeroNode; 49 | })(); 50 | -------------------------------------------------------------------------------- /node/IsNotZeroNode/img/IsNotZeroNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsNotZeroNode/img/IsNotZeroNode.png -------------------------------------------------------------------------------- /node/IsNotZeroNode/img/IsNotZeroNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsNotZeroNode/img/IsNotZeroNodePlot.png -------------------------------------------------------------------------------- /node/IsNotZeroNode/img/IsNotZeroNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsNotZeroNode/img/IsNotZeroNodeWaveShape.png -------------------------------------------------------------------------------- /node/IsNotZeroNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IsNotZeroNode 6 | 7 | 8 | 9 |

IsNotZeroNode

10 | 11 | 12 | 13 | 14 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /node/IsPositiveNode/IsPositiveNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws = np.zeros_like(x) 8 | ws[x > 0] = 1 9 | 10 | plt.subplot(111) 11 | plt.title("ws") 12 | plt.grid() 13 | plt.xlim(-1, 1) 14 | plt.ylim(-1.2, +1.2) 15 | plt.plot(x, ws) 16 | 17 | plt.savefig("%s/img/IsPositiveNodeWaveShape.png" % os.path.dirname(__file__)) 18 | -------------------------------------------------------------------------------- /node/IsPositiveNode/README.md: -------------------------------------------------------------------------------- 1 | # IsPositiveNode 2 | 3 | ### Expression 4 | 5 | `x = (a > 0) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/IsPositiveNode.png) 10 | 11 | ### WaveShape 12 | 13 | `ws = (x) -> (x > 0) ? 1 : 0` 14 | 15 | ![](img/IsPositiveNodeWaveShape.png) 16 | 17 | ### Plot 18 | 19 | ![](img/IsPositiveNodePlot.png) 20 | http://mohayonao.github.io/waa-lab/node/IsPositiveNode/ 21 | -------------------------------------------------------------------------------- /node/IsPositiveNode/createIsPositiveNode.js: -------------------------------------------------------------------------------- 1 | window.createIsPositiveNode = (function() { 2 | "use strict"; 3 | 4 | var EPSILON = 1e-4; 5 | var ws = createIsPositiveShaperCurve(65536); 6 | 7 | function createIsPositiveNode(context, a) { 8 | return createWaveShaperNode(context, ws, a); 9 | } 10 | 11 | function createIsPositiveShaperCurve(length) { 12 | var curve = new Float32Array(length); 13 | 14 | for (var i = 0; i < length; i++) { 15 | var x = (i / length) * 2 - 1; 16 | 17 | curve[i] = x > EPSILON ? 1 : 0; 18 | } 19 | 20 | return curve; 21 | } 22 | 23 | function createWaveShaperNode(context, curve, a) { 24 | var b = context.createWaveShaper(); 25 | 26 | b.curve = curve; 27 | 28 | a.connect(b); 29 | 30 | return b; 31 | } 32 | 33 | return createIsPositiveNode; 34 | })(); 35 | -------------------------------------------------------------------------------- /node/IsPositiveNode/img/IsPositiveNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsPositiveNode/img/IsPositiveNode.png -------------------------------------------------------------------------------- /node/IsPositiveNode/img/IsPositiveNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsPositiveNode/img/IsPositiveNodePlot.png -------------------------------------------------------------------------------- /node/IsPositiveNode/img/IsPositiveNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsPositiveNode/img/IsPositiveNodeWaveShape.png -------------------------------------------------------------------------------- /node/IsPositiveNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IsPositiveNode 6 | 7 | 8 | 9 |

IsPositiveNode

10 | 11 | 12 | 13 | 14 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /node/IsPositiveOrZeroNode/IsPositiveOrZeroNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws = np.zeros_like(x) 8 | ws[x >= 0] = 1 9 | 10 | plt.subplot(111) 11 | plt.title("ws") 12 | plt.grid() 13 | plt.xlim(-1, 1) 14 | plt.ylim(-1.2, +1.2) 15 | plt.plot(x, ws) 16 | 17 | plt.savefig("%s/img/IsPositiveOrZeroNodeWaveShape.png" % os.path.dirname(__file__)) 18 | -------------------------------------------------------------------------------- /node/IsPositiveOrZeroNode/README.md: -------------------------------------------------------------------------------- 1 | # IsPositiveOrZeroNode 2 | 3 | ### Expression 4 | 5 | `x = (a >= 0) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/IsPositiveOrZeroNode.png) 10 | 11 | ### WaveShape 12 | 13 | `ws = (x) -> (x >= 0) ? 1 : 0` 14 | 15 | ![](img/IsPositiveOrZeroNodeWaveShape.png) 16 | 17 | ### Plot 18 | 19 | ![](img/IsPositiveOrZeroNodePlot.png) 20 | http://mohayonao.github.io/waa-lab/node/IsPositiveOrZeroNode/ 21 | -------------------------------------------------------------------------------- /node/IsPositiveOrZeroNode/createIsPositiveOrZeroNode.js: -------------------------------------------------------------------------------- 1 | window.createIsPositiveOrZeroNode = (function() { 2 | "use strict"; 3 | 4 | var EPSILON = 1e-4; 5 | var ws = createIsPositiveOrZeroShaperCurve(65536); 6 | 7 | function createIsPositiveOrZeroNode(context, a) { 8 | return createWaveShaperNode(context, ws, a); 9 | } 10 | 11 | function createIsPositiveOrZeroShaperCurve(length) { 12 | var curve = new Float32Array(length); 13 | 14 | for (var i = 0; i < length; i++) { 15 | var x = (i / length) * 2 - 1; 16 | 17 | curve[i] = x >= -EPSILON ? 1 : 0; 18 | } 19 | 20 | return curve; 21 | } 22 | 23 | function createWaveShaperNode(context, curve, a) { 24 | var b = context.createWaveShaper(); 25 | 26 | b.curve = curve; 27 | 28 | a.connect(b); 29 | 30 | return b; 31 | } 32 | 33 | return createIsPositiveOrZeroNode; 34 | })(); 35 | -------------------------------------------------------------------------------- /node/IsPositiveOrZeroNode/img/IsPositiveOrZeroNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsPositiveOrZeroNode/img/IsPositiveOrZeroNode.png -------------------------------------------------------------------------------- /node/IsPositiveOrZeroNode/img/IsPositiveOrZeroNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsPositiveOrZeroNode/img/IsPositiveOrZeroNodePlot.png -------------------------------------------------------------------------------- /node/IsPositiveOrZeroNode/img/IsPositiveOrZeroNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsPositiveOrZeroNode/img/IsPositiveOrZeroNodeWaveShape.png -------------------------------------------------------------------------------- /node/IsPositiveOrZeroNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IsPositiveOrZeroNode 6 | 7 | 8 | 9 |

IsPositiveOrZeroNode

10 | 11 | 12 | 13 | 14 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /node/IsZeroNode/IsZeroNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws1 = np.zeros_like(x) 8 | ws2 = np.zeros_like(x) 9 | 10 | ws1[np.abs(x) <= 1e-4] = 1 11 | ws2[x > 0.99] = 1 12 | 13 | plt.subplot(211) 14 | plt.title("ws1") 15 | plt.grid() 16 | plt.xlim(-1, 1) 17 | plt.ylim(-1.2, +1.2) 18 | plt.plot(x, ws1) 19 | 20 | plt.subplot(212) 21 | plt.title("ws2") 22 | plt.grid() 23 | plt.xlim(-1, 1) 24 | plt.ylim(-1.2, +1.2) 25 | plt.plot(x, ws2) 26 | 27 | plt.savefig("%s/img/IsZeroNodeWaveShape.png" % os.path.dirname(__file__)) 28 | -------------------------------------------------------------------------------- /node/IsZeroNode/README.md: -------------------------------------------------------------------------------- 1 | # IsZeroNode 2 | 3 | ### Expression 4 | 5 | `x = (a == 0) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/IsZeroNode.png) 10 | 11 | ### WaveShape 12 | 13 | `ws = (x) -> (x == 0) ? 1 : 0` 14 | 15 | _ws2 is used to provide stability the output._ 16 | 17 | ![](img/IsZeroNodeWaveShape.png) 18 | 19 | ### Plot 20 | 21 | ![](img/IsZeroNodePlot.png) 22 | http://mohayonao.github.io/waa-lab/node/IsZeroNode/ 23 | -------------------------------------------------------------------------------- /node/IsZeroNode/createIsZeroNode.js: -------------------------------------------------------------------------------- 1 | window.createIsZeroNode = (function() { 2 | "use strict"; 3 | 4 | var EPSILON = 1e-4; 5 | var ws1 = createIsZeroShaperCurve(65536); 6 | var ws2 = createFixedCurve(2048); 7 | 8 | function createIsZeroNode(context, a) { 9 | var b = createWaveShaperNode(context, ws1, a); 10 | 11 | return createWaveShaperNode(context, ws2, b); 12 | } 13 | 14 | function createIsZeroShaperCurve(length) { 15 | var curve = new Float32Array(length); 16 | 17 | for (var i = 0; i < length; i++) { 18 | var x = (i / length) * 2 - 1; 19 | 20 | curve[i] = Math.abs(x) <= EPSILON ? 1 : 0; 21 | } 22 | 23 | return curve; 24 | } 25 | 26 | function createFixedCurve(length) { 27 | var curve = new Float32Array(length); 28 | 29 | for (var i = 0; i < length; i++) { 30 | var x = (i / length) * 2 - 1; 31 | 32 | curve[i] = x > 0.99 ? +1 : 0; 33 | } 34 | 35 | return curve; 36 | } 37 | 38 | function createWaveShaperNode(context, curve, a) { 39 | var b = context.createWaveShaper(); 40 | 41 | b.curve = curve; 42 | 43 | a.connect(b); 44 | 45 | return b; 46 | } 47 | 48 | return createIsZeroNode; 49 | })(); 50 | -------------------------------------------------------------------------------- /node/IsZeroNode/img/IsZeroNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsZeroNode/img/IsZeroNode.png -------------------------------------------------------------------------------- /node/IsZeroNode/img/IsZeroNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsZeroNode/img/IsZeroNodePlot.png -------------------------------------------------------------------------------- /node/IsZeroNode/img/IsZeroNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/IsZeroNode/img/IsZeroNodeWaveShape.png -------------------------------------------------------------------------------- /node/IsZeroNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IsZeroNode 6 | 7 | 8 | 9 |

IsZeroNode

10 | 11 | 12 | 13 | 14 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /node/MathAbsNode/README.md: -------------------------------------------------------------------------------- 1 | # MathAbsNode 2 | 3 | ### Expression 4 | 5 | `x = (a < 0) ? -a : a` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathAbsNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/MathAbsNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/MathAbsNode/ 15 | -------------------------------------------------------------------------------- /node/MathAbsNode/createMathAbsNode.js: -------------------------------------------------------------------------------- 1 | window.createMathAbsNode = (function() { 2 | "use strict"; 3 | 4 | function createMathAbsNode(context, a) { 5 | var b = createMathSignNode(context, a); 6 | 7 | return createMathMultiplyNode(context, a, b); 8 | } 9 | 10 | return createMathAbsNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/MathAbsNode/img/MathAbsNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathAbsNode/img/MathAbsNode.png -------------------------------------------------------------------------------- /node/MathAbsNode/img/MathAbsNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathAbsNode/img/MathAbsNodePlot.png -------------------------------------------------------------------------------- /node/MathAbsNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathAbsNode 6 | 7 | 8 | 9 |

MathAbsNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /node/MathAddNode/README.md: -------------------------------------------------------------------------------- 1 | # MathAddNode 2 | 3 | ### Expression 4 | 5 | `x = a + b` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathAddNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/MathAddNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/MathAddNode/ 15 | -------------------------------------------------------------------------------- /node/MathAddNode/createMathAddNode.js: -------------------------------------------------------------------------------- 1 | window.createMathAddNode = (function() { 2 | "use strict"; 3 | 4 | function createMathAddNode(context, a, b) { 5 | var x = context.createGain(); 6 | 7 | a.connect(x); 8 | b.connect(x); 9 | 10 | return x; 11 | } 12 | 13 | return createMathAddNode; 14 | })(); 15 | -------------------------------------------------------------------------------- /node/MathAddNode/img/MathAddNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathAddNode/img/MathAddNode.png -------------------------------------------------------------------------------- /node/MathAddNode/img/MathAddNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathAddNode/img/MathAddNodePlot.png -------------------------------------------------------------------------------- /node/MathAddNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathAddNode 6 | 7 | 8 | 9 |

MathAddNode

10 | 11 | 12 | 13 | 14 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /node/MathDivideNode/MathDivideNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws = np.array([ 1 / (x0 * 1000) for x0 in x ]) 8 | ws[ws > 1] = 1 9 | ws[ws < -1] = -1 10 | 11 | plt.subplot(111) 12 | plt.title("ws") 13 | plt.grid() 14 | plt.xlim(-1, 1) 15 | plt.ylim(-1.2, +1.2) 16 | plt.plot(x, ws) 17 | 18 | plt.savefig("%s/img/MathDivideNodeWaveShape.png" % os.path.dirname(__file__)) 19 | -------------------------------------------------------------------------------- /node/MathDivideNode/README.md: -------------------------------------------------------------------------------- 1 | # MathDivideNode 2 | 3 | ### Expression 4 | 5 | `x = a / b` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathDivideNode.png) 10 | 11 | ### WaveShape 12 | 13 | `ws = (x) -> x == 0 ? 1 : (1 / (x * MAX_VALUE))` 14 | 15 | ![](img/MathDivideNodeWaveShape.png) 16 | 17 | ### Plot 18 | 19 | _Green line represents ideal computed values._ 20 | 21 | ![](img/MathDivideNodePlot.png) 22 | http://mohayonao.github.io/waa-lab/node/MathDivideNode/ 23 | 24 | ### Note 25 | 26 | This method has an accuracy problem. So, this output does not strictly equal to the correct values. We need to choose better MAX_VALUE to improve the result. 27 | -------------------------------------------------------------------------------- /node/MathDivideNode/createMathDivideNode.js: -------------------------------------------------------------------------------- 1 | window.createMathDivideNode = (function() { 2 | "use strict"; 3 | 4 | var MAX_VALUE = 5000; 5 | var ws = createInverseShaperCurve(65536); 6 | 7 | function createMathDivideNode(context, a, b) { 8 | var c = createScaleGainNode(context, b, 1 / MAX_VALUE); 9 | var d = createWaveShaperNode(context, ws, c); 10 | 11 | return createMathMultiplyNode(context, a, d); 12 | } 13 | 14 | function shapeFn(value) { 15 | if (Math.fround(value) === 0) { 16 | return 1; 17 | } 18 | return 1 / (value * MAX_VALUE); 19 | } 20 | 21 | function createInverseShaperCurve(length) { 22 | var curve = new Float32Array(length); 23 | 24 | for (var i = 0; i < length; i++) { 25 | var x = (i / length) * 2 - 1; 26 | 27 | curve[i] = shapeFn(x); 28 | } 29 | 30 | return curve; 31 | } 32 | 33 | function createWaveShaperNode(context, curve, a) { 34 | var b = context.createWaveShaper(); 35 | 36 | b.curve = curve; 37 | 38 | a.connect(b); 39 | 40 | return b; 41 | } 42 | 43 | function createScaleGainNode(context, a, amp) { 44 | var b = context.createGain(); 45 | 46 | b.gain.value = amp; 47 | 48 | a.connect(b); 49 | 50 | return b; 51 | } 52 | 53 | return createMathDivideNode; 54 | })(); 55 | -------------------------------------------------------------------------------- /node/MathDivideNode/img/MathDivideNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathDivideNode/img/MathDivideNode.png -------------------------------------------------------------------------------- /node/MathDivideNode/img/MathDivideNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathDivideNode/img/MathDivideNodePlot.png -------------------------------------------------------------------------------- /node/MathDivideNode/img/MathDivideNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathDivideNode/img/MathDivideNodeWaveShape.png -------------------------------------------------------------------------------- /node/MathDivideNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathDivideNode 6 | 7 | 8 | 9 |

MathDivideNode

10 | 11 | 12 | 13 | 14 | 15 | 138 | 139 | 140 | -------------------------------------------------------------------------------- /node/MathInvertNode/README.md: -------------------------------------------------------------------------------- 1 | # MathInvertNode 2 | 3 | ### Expression 4 | 5 | `x = -a` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathInvertNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/MathInvertNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/MathInvertNode/ 15 | -------------------------------------------------------------------------------- /node/MathInvertNode/createMathInvertNode.js: -------------------------------------------------------------------------------- 1 | window.createMathInvertNode = (function() { 2 | "use strict"; 3 | 4 | function createMathInvertNode(context, a) { 5 | var b = context.createGain(); 6 | 7 | b.gain.value = -1; 8 | 9 | a.connect(b); 10 | 11 | return b; 12 | } 13 | 14 | return createMathInvertNode; 15 | })(); 16 | -------------------------------------------------------------------------------- /node/MathInvertNode/img/MathInvertNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathInvertNode/img/MathInvertNode.png -------------------------------------------------------------------------------- /node/MathInvertNode/img/MathInvertNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathInvertNode/img/MathInvertNodePlot.png -------------------------------------------------------------------------------- /node/MathInvertNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathInvertNode 6 | 7 | 8 | 9 |

MathInvertNode

10 | 11 | 12 | 13 | 14 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /node/MathMaxNode/README.md: -------------------------------------------------------------------------------- 1 | # MathMaxNode 2 | 3 | ### Expression 4 | 5 | `x = (a >= b) ? a : b` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathMaxNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/MathMaxNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/MathMaxNode/ 15 | -------------------------------------------------------------------------------- /node/MathMaxNode/createMathMaxNode.js: -------------------------------------------------------------------------------- 1 | window.createMathMaxNode = (function() { 2 | "use strict"; 3 | 4 | function createMathMaxNode(context, a, b) { 5 | var c = createMathSubtractNode(context, a, b); 6 | var a0 = createIsPositiveOrZeroNode(context, c); 7 | var a1 = createMathMultiplyNode(context, a, a0); 8 | var b0 = createIsNegativeNode(context, c); 9 | var b1 = createMathMultiplyNode(context, b, b0); 10 | 11 | return createMathAddNode(context, a1, b1); 12 | } 13 | 14 | return createMathMaxNode; 15 | })(); 16 | -------------------------------------------------------------------------------- /node/MathMaxNode/img/MathMaxNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathMaxNode/img/MathMaxNode.png -------------------------------------------------------------------------------- /node/MathMaxNode/img/MathMaxNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathMaxNode/img/MathMaxNodePlot.png -------------------------------------------------------------------------------- /node/MathMaxNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathMaxNode 6 | 7 | 8 | 9 |

MathMaxNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /node/MathMultiplyNode/README.md: -------------------------------------------------------------------------------- 1 | # MathMultiplyNode 2 | 3 | ### Expression 4 | 5 | `x = a * b` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathMultiplyNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/MathMultiplyNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/MathMultiplyNode/ 15 | -------------------------------------------------------------------------------- /node/MathMultiplyNode/createMathMultiplyNode.js: -------------------------------------------------------------------------------- 1 | window.createMathMultiplyNode = (function() { 2 | "use strict"; 3 | 4 | function createMathMultiplyNode(context, a, b) { 5 | var c = context.createGain(); 6 | 7 | a.connect(c); 8 | b.connect(c.gain); 9 | 10 | c.gain.value = 0; 11 | 12 | return c; 13 | } 14 | 15 | return createMathMultiplyNode; 16 | })(); 17 | -------------------------------------------------------------------------------- /node/MathMultiplyNode/img/MathMultiplyNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathMultiplyNode/img/MathMultiplyNode.png -------------------------------------------------------------------------------- /node/MathMultiplyNode/img/MathMultiplyNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathMultiplyNode/img/MathMultiplyNodePlot.png -------------------------------------------------------------------------------- /node/MathMultiplyNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathMultiplyNode 6 | 7 | 8 | 9 |

MathMultiplyNode

10 | 11 | 12 | 13 | 14 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /node/MathSignNode/MathSignNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.linspace(-1.0, 1.0, 10000, endpoint=True) 6 | 7 | ws = np.sign(x) 8 | 9 | plt.subplot(111) 10 | plt.title("ws") 11 | plt.grid() 12 | plt.xlim(-1, 1) 13 | plt.ylim(-1.2, +1.2) 14 | plt.plot(x, ws) 15 | 16 | plt.savefig("%s/img/MathSignNodeWaveShape.png" % os.path.dirname(__file__)) 17 | -------------------------------------------------------------------------------- /node/MathSignNode/README.md: -------------------------------------------------------------------------------- 1 | # MathSignNode 2 | 3 | ### Expression 4 | 5 | `x = (a == 0) ? 0 : (a < 0) ? -1 : 1` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathSignNode.png) 10 | 11 | ### WaveShape 12 | 13 | `ws = (x) -> (x == 0) ? 0 : (x < 0) ? -1 : 1` 14 | 15 | ![](img/MathSignNodeWaveShape.png) 16 | 17 | ### Plot 18 | 19 | ![](img/MathSignNodePlot.png) 20 | http://mohayonao.github.io/waa-lab/node/MathSignNode/ 21 | -------------------------------------------------------------------------------- /node/MathSignNode/createMathSignNode.js: -------------------------------------------------------------------------------- 1 | window.createMathSignNode = (function() { 2 | "use strict"; 3 | 4 | var EPSILON = 1e-4; 5 | var ws = createMathSignShaperCurve(65536); 6 | 7 | function createMathSignNode(context, a) { 8 | return createWaveShaperNode(context, ws, a); 9 | } 10 | 11 | function createMathSignShaperCurve(length) { 12 | var curve = new Float32Array(length); 13 | 14 | for (var i = 0; i < length; i++) { 15 | var x = (i / length) * 2 - 1; 16 | 17 | curve[i] = Math.abs(x) < EPSILON ? 0 : x < 0 ? -1 : +1; 18 | } 19 | 20 | return curve; 21 | } 22 | 23 | function createWaveShaperNode(context, curve, a) { 24 | var b = context.createWaveShaper(); 25 | 26 | b.curve = curve; 27 | 28 | a.connect(b); 29 | 30 | return b; 31 | } 32 | 33 | return createMathSignNode; 34 | })(); 35 | -------------------------------------------------------------------------------- /node/MathSignNode/img/MathSignNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathSignNode/img/MathSignNode.png -------------------------------------------------------------------------------- /node/MathSignNode/img/MathSignNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathSignNode/img/MathSignNodePlot.png -------------------------------------------------------------------------------- /node/MathSignNode/img/MathSignNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathSignNode/img/MathSignNodeWaveShape.png -------------------------------------------------------------------------------- /node/MathSignNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathSignNode 6 | 7 | 8 | 9 |

MathSignNode

10 | 11 | 12 | 13 | 14 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /node/MathSubtractNode/README.md: -------------------------------------------------------------------------------- 1 | # MathSubtractNode 2 | 3 | ### Expression 4 | 5 | `x = a - b` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/MathSubtractNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/MathSubtractNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/MathSubtractNode/ 15 | -------------------------------------------------------------------------------- /node/MathSubtractNode/createMathSubtractNode.js: -------------------------------------------------------------------------------- 1 | window.createMathSubtractNode = (function() { 2 | "use strict"; 3 | 4 | function createMathSubtractNode(context, a, b) { 5 | var c = createMathInvertNode(context, b); 6 | 7 | return createMathAddNode(context, a, c); 8 | } 9 | 10 | return createMathSubtractNode; 11 | })(); 12 | -------------------------------------------------------------------------------- /node/MathSubtractNode/img/MathSubtractNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathSubtractNode/img/MathSubtractNode.png -------------------------------------------------------------------------------- /node/MathSubtractNode/img/MathSubtractNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/MathSubtractNode/img/MathSubtractNodePlot.png -------------------------------------------------------------------------------- /node/MathSubtractNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MathSubtractNode 6 | 7 | 8 | 9 |

MathSubtractNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /node/SwitchNode/README.md: -------------------------------------------------------------------------------- 1 | # SwitchNode 2 | 3 | ### Expression 4 | 5 | `x = a * ((c > 0) ? 1 : 0) + b * ((c < 0) ? 1 : 0)` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/SwitchNode.png) 10 | 11 | ### WaveShape 12 | 13 | - `ws1 = (x) -> (x > 0) ? 1 : 0` 14 | - `ws2 = (x) -> (x < 0) ? 1 : 0` 15 | 16 | ![](img/SwitchNodeWaveShape.png) 17 | 18 | ### Plot 19 | 20 | ![](img/SwitchNodePlot.png) 21 | http://mohayonao.github.io/waa-lab/node/SwitchNode/ 22 | -------------------------------------------------------------------------------- /node/SwitchNode/SwitchNodeWaveShape.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | x = np.arange(-1.0, 1.0, 0.0001) 6 | 7 | ws1 = np.zeros_like(x) 8 | ws1[x > 0] = 1 9 | 10 | ws2 = np.zeros_like(x) 11 | ws2[x < 0] = 1 12 | 13 | plt.subplot(211) 14 | plt.title("ws1") 15 | plt.grid() 16 | plt.xlim(-1, 1) 17 | plt.ylim(-1.2, +1.2) 18 | plt.plot(x, ws1) 19 | 20 | plt.subplot(212) 21 | plt.title("ws2") 22 | plt.grid() 23 | plt.xlim(-1, 1) 24 | plt.ylim(-1.2, +1.2) 25 | plt.plot(x, ws2) 26 | 27 | plt.savefig("%s/img/SwitchNodeWaveShape.png" % os.path.dirname(__file__)) 28 | -------------------------------------------------------------------------------- /node/SwitchNode/createSwitchNode.js: -------------------------------------------------------------------------------- 1 | window.createSwitchNode = (function() { 2 | "use strict"; 3 | 4 | var ws1 = createSelectAShaperCurve(8192); 5 | var ws2 = createSelectBShaperCurve(8192); 6 | 7 | function createSwitchNode(context, a, b, c) { 8 | var a0 = createWaveShaperNode(context, ws1, c); 9 | var b0 = createWaveShaperNode(context, ws2, c); 10 | var a1 = createMathMultiplyNode(context, a, a0); 11 | var b1 = createMathMultiplyNode(context, b, b0); 12 | 13 | return createMathAddNode(context, a1, b1); 14 | } 15 | 16 | function createSelectAShaperCurve(length) { 17 | var curve = new Float32Array(length); 18 | 19 | for (var i = 0; i < length; i++) { 20 | var x = (i / length) * 2 - 1; 21 | 22 | curve[i] = x > 0 ? 1 : 0; 23 | } 24 | 25 | return curve; 26 | } 27 | 28 | function createSelectBShaperCurve(length) { 29 | var curve = new Float32Array(length); 30 | 31 | for (var i = 0; i < length; i++) { 32 | var x = (i / length) * 2 - 1; 33 | 34 | curve[i] = x < 0 ? 1 : 0; 35 | } 36 | 37 | return curve; 38 | } 39 | 40 | function createWaveShaperNode(context, curve, a) { 41 | var b = context.createWaveShaper(); 42 | 43 | b.curve = curve; 44 | 45 | a.connect(b); 46 | 47 | return b; 48 | } 49 | 50 | return createSwitchNode; 51 | })(); 52 | -------------------------------------------------------------------------------- /node/SwitchNode/img/SwitchNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/SwitchNode/img/SwitchNode.png -------------------------------------------------------------------------------- /node/SwitchNode/img/SwitchNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/SwitchNode/img/SwitchNodePlot.png -------------------------------------------------------------------------------- /node/SwitchNode/img/SwitchNodeWaveShape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/SwitchNode/img/SwitchNodeWaveShape.png -------------------------------------------------------------------------------- /node/SwitchNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SwitchNode 6 | 7 | 8 | 9 |

SwitchNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /node/ZeroCrossingNode/README.md: -------------------------------------------------------------------------------- 1 | # ZeroCrossingNode 2 | 3 | ### Expression 4 | 5 | `x = ((sign(a[t]) - sign(a[t-1])) != 0) ? 1 : 0` 6 | 7 | ### AudioGraph 8 | 9 | ![](img/ZeroCrossingNode.png) 10 | 11 | ### Plot 12 | 13 | ![](img/ZeroCrossingNodePlot.png) 14 | http://mohayonao.github.io/waa-lab/node/ZeroCrossingNode/ 15 | -------------------------------------------------------------------------------- /node/ZeroCrossingNode/createZeroCrossingNode.js: -------------------------------------------------------------------------------- 1 | window.createZeroCrossingNode = (function() { 2 | "use strict"; 3 | 4 | 5 | function createZeroCrossingNode(context, a) { 6 | var b = createMathSignNode(context, a); 7 | var c = createDelay1Node(context, b); 8 | var d = createMathSignNode(context, c); 9 | var e = createMathSubtractNode(context, b, d); 10 | 11 | return createIsNotZeroNode(context, e); 12 | } 13 | 14 | function createDelay1Node(context, a) { 15 | var delayTime = 1 / context.sampleRate; 16 | var b = context.createDelay(delayTime); 17 | 18 | a.connect(b); 19 | 20 | b.delayTime.value = delayTime; 21 | 22 | return b; 23 | } 24 | 25 | return createZeroCrossingNode; 26 | })(); 27 | -------------------------------------------------------------------------------- /node/ZeroCrossingNode/img/ZeroCrossingNode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/ZeroCrossingNode/img/ZeroCrossingNode.png -------------------------------------------------------------------------------- /node/ZeroCrossingNode/img/ZeroCrossingNodePlot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/node/ZeroCrossingNode/img/ZeroCrossingNodePlot.png -------------------------------------------------------------------------------- /node/ZeroCrossingNode/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ZeroCrossingNode 6 | 7 | 8 | 9 |

ZeroCrossingNode

10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /research/audio-node-default-channel-configuration.md: -------------------------------------------------------------------------------- 1 | # AudioNode - Default Channel Configuration 2 | 3 | | name | inputs | outputs | channel count | count mode | interpretation | 4 | |------|--------|---------|---------------|------------|----------------| 5 | | AudioDestinationNode | 1 | 0 | 2 | explicit | speakers | 6 | | GainNode | 1 | 1 | - | max | speakers | 7 | | DelayNode | 1 | 1 | - | max | speakers | 8 | | AudioBufferSourceNode | 0 | 1 | - | - | - | 9 | | MediaElementAudioSourceNode | 0 | 1 | - | - | - | 10 | | AudioWorkerNode |var|var|var| explicit | speakers | 11 | | ScriptProcessorNode | 1 | 1 |_N_| explicit | speakers | 12 | | PannerNode | 1 | 1 | 2 | clamped-max | speakers | 13 | | SpatialPannerNode | 1 | 1 | 2 | clamped-max | speakers | 14 | | StereoPannerNode | 1 | 1 | 2 | clamped-max | speakers | 15 | | ConvolverNode | 1 | 1 | 2 | clamped-max | speakers | 16 | | AnalyserNode | 1 | 1 | 1 | max | speakers | 17 | | ChannelSplitterNode | 1 |_N_| - | max | speakers | 18 | | ChannelMergerNode |_N_| 1 | 1 | explicit | speakers | 19 | | DynamicsCompressorNode | 1 | 1 | 2 | explicit | speakers | 20 | | BiquadFilterNode | 1 | 1 | - | max | speakers | 21 | | IIRFilterNode | 1 | 1 | - | max | speakers | 22 | | WaveShaperNode | 1 | 1 | - | max | speakers | 23 | | OscillatorNode | 0 | 1 | - | - | - | 24 | | MediaStreamAudioSourceNode | 0 | 1 | - | - | - | 25 | | MediaStreamAudioDestinationNode | 1 | 0 | 2 | explicit | speakers | 26 | -------------------------------------------------------------------------------- /research/audio-param-set-value-curve-at-time-interpolation/README.md: -------------------------------------------------------------------------------- 1 | # AudioParam - setValueCurveAtTime Interpolation 2 | 3 | ### Comparison 4 | 5 | ![](img/comparison.png) 6 | 7 | ### Simulator 8 | 9 | ```js 10 | function spec(x, curve) { 11 | var ix, i0, i1, y0, y1, a; 12 | 13 | x = Math.max(-1, Math.min(x, 1)); 14 | x = (x + 1) * 0.5; 15 | 16 | ix = x * (curve.length - 1); 17 | i0 = ix|0; 18 | i1 = i0 + 1; 19 | 20 | if (curve.length <= i1) { 21 | return curve[curve.length - 1]; 22 | } 23 | 24 | y0 = curve[i0]; 25 | y1 = curve[i1]; 26 | a = ix % 1; 27 | 28 | return y0 + a * (y1 - y0); 29 | } 30 | 31 | function firefox(x, curve) { 32 | var i; 33 | 34 | x = Math.max(-1, Math.min(x, 1)); 35 | x = (x + 1) * 0.5; 36 | 37 | i = (x * curve.length)|0; 38 | i = Math.min(i, curve.length - 1); 39 | 40 | return curve[i]; 41 | } 42 | 43 | function safari(x, curve) { 44 | var i; 45 | 46 | x = Math.max(-1, Math.min(x, 1)); 47 | x = (x + 1) * 0.5; 48 | x = x + (0.5 / curve.length); 49 | 50 | i = (x * curve.length)|0; 51 | i = Math.min(i, curve.length - 1); 52 | 53 | return curve[i]; 54 | } 55 | ``` 56 | 57 | ### Try It 58 | http://mohayonao.github.io/waa-lab/research/audio-param-set-value-curve-at-time-interpolation/ 59 | -------------------------------------------------------------------------------- /research/audio-param-set-value-curve-at-time-interpolation/img/comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/research/audio-param-set-value-curve-at-time-interpolation/img/comparison.png -------------------------------------------------------------------------------- /research/audio-param-set-value-curve-at-time-interpolation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AudioParam - setValueCurveAtTime Interpolation 6 | 7 | 8 | 9 |

AudioParam - setValueCurveAtTime Interpolation

10 | 11 | 12 | 13 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /research/audio-param-set-value-curve-at-time-interpolation/value-curve.js: -------------------------------------------------------------------------------- 1 | function spec(x, curve) { 2 | var ix, i0, i1, y0, y1, a; 3 | 4 | x = Math.max(-1, Math.min(x, 1)); 5 | x = (x + 1) * 0.5; 6 | 7 | ix = x * (curve.length - 1); 8 | i0 = ix|0; 9 | i1 = i0 + 1; 10 | 11 | if (curve.length <= i1) { 12 | return curve[curve.length - 1]; 13 | } 14 | 15 | y0 = curve[i0]; 16 | y1 = curve[i1]; 17 | a = ix % 1; 18 | 19 | return y0 + a * (y1 - y0); 20 | } 21 | 22 | function firefox(x, curve) { 23 | var i; 24 | 25 | x = Math.max(-1, Math.min(x, 1)); 26 | x = (x + 1) * 0.5; 27 | 28 | i = (x * curve.length)|0; 29 | i = Math.min(i, curve.length - 1); 30 | 31 | return curve[i]; 32 | } 33 | 34 | function safari(x, curve) { 35 | var i; 36 | 37 | x = Math.max(-1, Math.min(x, 1)); 38 | x = (x + 1) * 0.5; 39 | x = x + (0.5 / curve.length); 40 | 41 | i = (x * curve.length)|0; 42 | i = Math.min(i, curve.length - 1); 43 | 44 | return curve[i]; 45 | } 46 | 47 | function calcDifference(x, curve) { 48 | var y = 0; 49 | 50 | for (var i = 0; i < x.length; i++) { 51 | y += Math.pow(spec(x[i], curve) - safari(x[i], curve), 2); 52 | } 53 | y /= x.length; 54 | 55 | return Math.sqrt(y) * 0.5; 56 | } 57 | 58 | 59 | var curve = [ -1, -0.5, 0, 0.5, 1 ]; 60 | var x = new Float32Array(1024); 61 | 62 | for (var i = 0; i < x.length; i++) { 63 | x[i] = ((i / x.length) - 0.5) * 2; 64 | } 65 | console.log(calcDifference(x, curve)); 66 | -------------------------------------------------------------------------------- /research/audio-param-set-value-curve-at-time-interpolation/value-curve.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | def spec(x, curve): 6 | x = max(-1, min(x, 1)) 7 | x = (x + 1) * 0.5 8 | 9 | ix = x * (len(curve) - 1) 10 | i0 = int(ix) 11 | i1 = i0 + 1 12 | 13 | if len(curve) <= i1: 14 | return curve[-1] 15 | 16 | y0, y1 = curve[i0:i1+1] 17 | a = ix % 1.0 18 | 19 | return y0 + a * (y1 - y0) 20 | 21 | def firefox(x, curve): 22 | x = max(-1, min(x, 1)) 23 | x = (x + 1) * 0.5 24 | 25 | i = int(x * len(curve)) 26 | i = min(i, len(curve) - 1) 27 | 28 | return curve[i] 29 | 30 | def safari(x, curve): 31 | x = max(-1, min(x, 1)) 32 | x = (x + 1) * 0.5 33 | x = x + (0.5 / len(curve)) 34 | 35 | i = int(x * len(curve)) 36 | i = min(i, len(curve) - 1) 37 | 38 | return curve[i] 39 | 40 | def ws(wsfunc, curve): 41 | def pyfunc(x): 42 | return wsfunc(x, curve) 43 | return pyfunc 44 | 45 | def calc_difference(y1, y2): 46 | return np.sqrt(np.mean((y1 - y2) ** 2)) * 0.5 47 | 48 | curve = np.array([ -1, -0.5, 0, 0.5, 1 ]) 49 | 50 | x = np.linspace(-1, 1, 10000, endpoint=True) 51 | 52 | plt.title("AudioParam#setValueCurveAtTime interpolation") 53 | plt.xlim(-1, 1) 54 | plt.ylim(-1.1, 1.1) 55 | 56 | y1 = np.vectorize(ws(spec, curve))(x) 57 | plt.plot(x, y1, label="Chrome 48 (latest spec)", lw=2) 58 | 59 | y2 = np.vectorize(ws(firefox, curve))(x) 60 | plt.plot(x, y2, label="Firefox 44") 61 | 62 | y3 = np.vectorize(ws(safari, curve))(x) 63 | plt.plot(x, y3, label="Safari 9/iOS9 Mobile Safari") 64 | 65 | plt.legend(loc="lower right") 66 | plt.grid() 67 | plt.savefig("%s/img/comparison.png" % os.path.dirname(__file__)) 68 | 69 | print "length: %d" % len(curve) 70 | print "safari: %f" % calc_difference(y1, y2) 71 | -------------------------------------------------------------------------------- /research/audio-utils-the-valid-range-of-parameters.md: -------------------------------------------------------------------------------- 1 | # AudioUtils - The Valid Range of Parameters 2 | 3 | > :bow: Please PR to fill the MS Edge data!! 4 | 5 | ## AudioBuffer 6 | 7 | #### sampleRate 8 | 9 | | browser | min | max | ref | 10 | |---------|-------:|-------:|------| 11 | | _spec_ | 8192 | 96000 | [2.1.2 The BaseAudioContext Interface methods](https://www.w3.org/TR/webaudio/#methods) | 12 | | blink | 3000 | 192000 | [AudioBuffer.cpp](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/AudioBuffer.cpp#46) -> [AudioUtilities.cpp](https://chromium.googlesource.com/chromium/blink/+/master/Source/platform/audio/AudioUtilities.cpp#65) | 13 | | gecko | 8000 | 192000 | [AudioBuffer.cpp](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/AudioBuffer.cpp#l79) -> [WebAudioUtils.h](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/WebAudioUtils.h#l38) | 14 | | webkit | 22050 | 96000 | [AudioBuffer.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/AudioBuffer.cpp#L48) | 15 | 16 | #### numberOfChannels 17 | 18 | | browser | min | max | ref | 19 | |---------|-------:|-------:|------| 20 | | _spec_ | 1 | 32 | [2.1.2 The BaseAudioContext Interface methods](https://www.w3.org/TR/webaudio/#methods) | 21 | | blink | 1 | 32 | [AudioBuffer.cpp](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/AudioBuffer.cpp#46) -> [AbstractAudioContext.h](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/AbstractAudioContext.h#321) | 22 | | gecko | 1 | 32 | [AudioBuffer.cpp](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/AudioBuffer.cpp#l81) -> [WebAudioUtils.h](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/WebAudioUtils.h#l35) 23 | | webkit | 1 | 32 | [AudioBuffer.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/AudioBuffer.cpp#L48) -> [AudioContext.h](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/AudioContext.h#L391) | 24 | 25 | ## OfflineAudioContext 26 | 27 | #### sampleRate 28 | 29 | | browser | min | max | ref | 30 | |---------|-------:|-------:|------| 31 | | _spec_ | 8192 | 96000 | [2.3 The OfflineAudioContext Interface](https://www.w3.org/TR/webaudio/#OfflineAudioContext) | 32 | | blink | 3000 | 192000 | [OfflineAudioContext.cpp](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/OfflineAudioContext.cpp#69) -> [AudioUtilities.cpp](https://chromium.googlesource.com/chromium/blink/+/master/Source/platform/audio/AudioUtilities.cpp#65) | 33 | | gecko | 8000 | 192000 | [AudioContext.cpp](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/AudioContext.cpp#l207) -> [WebAudioUtils.h](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/WebAudioUtils.h#l38) | 34 | | webkit | 44100 | 96000 | [OfflineAudioContext.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp#L47) -> [AudioContext.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp#L106) | 35 | 36 | #### numberOfChannels 37 | 38 | | browser | min | max | ref | 39 | |---------|-------:|-------:|------| 40 | | _spec_ | 1 | 32 | [2.3 The OfflineAudioContext Interface](https://www.w3.org/TR/webaudio/#OfflineAudioContext) | 41 | | blink | 1 | 32 | [OfflineAudioContext.cpp](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/OfflineAudioContext.cpp#56) -> [AbstractAudioContext.h](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/AbstractAudioContext.h#321) | 42 | | gecko | 1 | 32 | [AudioContext.cpp](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/AudioContext.cpp#l205) -> [WebAudioUtils.h](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/WebAudioUtils.h#l35) | 43 | | webkit | 1 | 10 | [OfflineAudioContext.cpp#](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/OfflineAudioContext.cpp#L47) | 44 | 45 | ## AnalyserNode 46 | 47 | #### fftSize 48 | 49 | | browser | min | max | ref | 50 | |---------|-------:|-------:|------| 51 | | _spec_ | 32 | 32768 | [2.23 The AnalyserNode Interface](https://www.w3.org/TR/webaudio/#the-analysernode-interface) | 52 | | blink | 32 | 32768 | [AnalyserNode](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/AnalyserNode.cpp#75) -> [RealtimeAnalyser.cpp](https://chromium.googlesource.com/chromium/blink/+/master/Source/modules/webaudio/RealtimeAnalyser.cpp#46) | 53 | | gecko | 32 | 32768 | [AnalyserNode.cpp](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/AnalyserNode.cpp#l152) -> [AnalyserNode.cpp](https://hg.mozilla.org/mozilla-central/file/tip/dom/media/webaudio/AnalyserNode.cpp#l16) | 54 | | webkit | 32 | 2048 | [AnalyserNode.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/AnalyserNode.cpp#L75) -> [RealtimeAnalyser.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/RealtimeAnalyser.cpp#L49) | 55 | 56 | ## PeriodicWave 57 | 58 | #### length 59 | 60 | | browser | min | max | ref | 61 | |---------|-------:|-------:|------| 62 | | _spec_ | 1 | - | | 63 | | blink | 1 | - | | 64 | | gecko | 1 | 4096 | ? | 65 | | webkit | 1 | 4096 | [AudioContext.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp#L657) -> [AudioContext.cpp](https://trac.webkit.org/browser/trunk/Source/WebCore/Modules/webaudio/AudioContext.cpp#L102) | 66 | -------------------------------------------------------------------------------- /research/wave-shaper-node-interpolation/README.md: -------------------------------------------------------------------------------- 1 | # WaveShaperNode - Interpolation 2 | 3 | ### Comparison 4 | 5 | ![](img/comparison.png) 6 | 7 | ### Simulator 8 | 9 | ```js 10 | function spec(x, curve) { 11 | var ix, i0, i1, y0, y1, a; 12 | 13 | x = Math.max(-1, Math.min(x, 1)); 14 | x = (x + 1) * 0.5; 15 | 16 | ix = x * (curve.length - 1); 17 | i0 = ix|0; 18 | i1 = i0 + 1; 19 | 20 | if (curve.length <= i1) { 21 | return curve[curve.length - 1]; 22 | } 23 | 24 | y0 = curve[i0]; 25 | y1 = curve[i1]; 26 | a = ix % 1; 27 | 28 | return y0 + a * (y1 - y0); 29 | } 30 | 31 | function safari(x, curve) { 32 | var ix, i0, i1, y0, y1, a; 33 | 34 | x = Math.max(-1, Math.min(x, 1)); 35 | x = (x + 1) * 0.5; 36 | 37 | ix = x * curve.length; 38 | i0 = ix|0; 39 | i1 = i0 + 1; 40 | 41 | if (curve.length <= i1) { 42 | return curve[curve.length - 1]; 43 | } 44 | 45 | y0 = curve[i0]; 46 | y1 = curve[i1]; 47 | a = ix % 1; 48 | 49 | return y0 + a * (y1 - y0); 50 | } 51 | 52 | function noInterp(x, curve) { 53 | var i; 54 | 55 | x = Math.max(-1, Math.min(x, 1)); 56 | x = (x + 1) * 0.5; 57 | 58 | i = (x * curve.length)|0; 59 | i = Math.min(i, curve.length - 1); 60 | 61 | return curve[i]; 62 | } 63 | ``` 64 | 65 | ### Try It 66 | http://mohayonao.github.io/waa-lab/research/wave-shaper-node-interpolation/ 67 | -------------------------------------------------------------------------------- /research/wave-shaper-node-interpolation/img/comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mohayonao/waa-lab/b6ea2c53412e7134504d712180e8f95ce58063ee/research/wave-shaper-node-interpolation/img/comparison.png -------------------------------------------------------------------------------- /research/wave-shaper-node-interpolation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | WaveShaperNode - Interpolation 6 | 7 | 8 | 9 |

WaveShaperNode - Interpolation

10 | 11 | 12 | 13 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /research/wave-shaper-node-interpolation/wave-shaper.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | def spec(x, curve): 6 | x = max(-1, min(x, 1)) 7 | x = (x + 1) * 0.5 8 | 9 | ix = x * (len(curve) - 1) 10 | i0 = int(ix) 11 | i1 = i0 + 1 12 | 13 | if len(curve) <= i1: 14 | return curve[-1] 15 | 16 | y0, y1 = curve[i0:i1+1] 17 | a = ix % 1.0 18 | 19 | return y0 + a * (y1 - y0) 20 | 21 | def safari(x, curve): 22 | x = max(-1, min(x, 1)) 23 | x = (x + 1) * 0.5 24 | 25 | ix = x * len(curve) 26 | i0 = int(ix) 27 | i1 = i0 + 1 28 | 29 | if len(curve) <= i1: 30 | return curve[-1] 31 | 32 | y0, y1 = curve[i0:i1+1] 33 | a = ix % 1.0 34 | 35 | return y0 + a * (y1 - y0) 36 | 37 | def no_interp(x, curve): 38 | x = max(-1, min(x, 1)) 39 | x = (x + 1) * 0.5 40 | 41 | i = int(x * len(curve)) 42 | i = min(i, len(curve) - 1) 43 | 44 | return curve[i] 45 | 46 | def ws(wsfunc, curve): 47 | def pyfunc(x): 48 | return wsfunc(x, curve) 49 | return pyfunc 50 | 51 | def calc_difference(y1, y2): 52 | return np.sqrt(np.mean((y1 - y2) ** 2)) * 0.5 53 | 54 | curve = np.linspace(-1, 1, 2, endpoint=True) 55 | curve = np.array([ -1, -0.5, 0, 0.5, 1 ]) 56 | 57 | x = np.linspace(-1, 1, 10000, endpoint=True) 58 | 59 | plt.title("WaveShaper interpolation") 60 | plt.xlim(-1, 1) 61 | plt.ylim(-1.1, 1.1) 62 | 63 | y1 = np.vectorize(ws(spec, curve))(x) 64 | plt.plot(x, y1, label="Chrome 48/Firefox 44 (latest spec)", lw=2) 65 | 66 | y2 = np.vectorize(ws(safari, curve))(x) 67 | plt.plot(x, y2, label="Safari 9/iOS9 Mobile Safari (bug?)") 68 | 69 | y3 = np.vectorize(ws(no_interp, curve))(x) 70 | plt.plot(x, y3, label="iOS7 Mobile Safari (old API)") 71 | 72 | plt.legend(loc="lower right") 73 | plt.grid() 74 | plt.savefig("%s/img/comparison.png" % os.path.dirname(__file__)) 75 | 76 | print "length: %d" % len(curve) 77 | print "safari: %f" % calc_difference(y1, y2) 78 | print "no-interp: %f" % calc_difference(y1, y3) 79 | -------------------------------------------------------------------------------- /research/wave-shaper-node-interpolation/wave-sheper.js: -------------------------------------------------------------------------------- 1 | function spec(x, curve) { 2 | var ix, i0, i1, y0, y1, a; 3 | 4 | x = Math.max(-1, Math.min(x, 1)); 5 | x = (x + 1) * 0.5; 6 | 7 | ix = x * (curve.length - 1); 8 | i0 = ix|0; 9 | i1 = i0 + 1; 10 | 11 | if (curve.length <= i1) { 12 | return curve[curve.length - 1]; 13 | } 14 | 15 | y0 = curve[i0]; 16 | y1 = curve[i1]; 17 | a = ix % 1; 18 | 19 | return y0 + a * (y1 - y0); 20 | } 21 | 22 | function safari(x, curve) { 23 | var ix, i0, i1, y0, y1, a; 24 | 25 | x = Math.max(-1, Math.min(x, 1)); 26 | x = (x + 1) * 0.5; 27 | 28 | ix = x * curve.length; 29 | i0 = ix|0; 30 | i1 = i0 + 1; 31 | 32 | if (curve.length <= i1) { 33 | return curve[curve.length - 1]; 34 | } 35 | 36 | y0 = curve[i0]; 37 | y1 = curve[i1]; 38 | a = ix % 1; 39 | 40 | return y0 + a * (y1 - y0); 41 | } 42 | 43 | function noInterp(x, curve) { 44 | var i; 45 | 46 | x = Math.max(-1, Math.min(x, 1)); 47 | x = (x + 1) * 0.5; 48 | 49 | i = (x * curve.length)|0; 50 | i = Math.min(i, curve.length - 1); 51 | 52 | return curve[i]; 53 | } 54 | 55 | function calcDifference(x, curve) { 56 | var y = 0; 57 | 58 | for (var i = 0; i < x.length; i++) { 59 | y += Math.pow(spec(x[i], curve) - safari(x[i], curve), 2); 60 | } 61 | y /= x.length; 62 | 63 | return Math.sqrt(y) * 0.5; 64 | } 65 | 66 | 67 | var curve = [ -1, -0.5, 0, 0.5, 1 ]; 68 | var x = new Float32Array(1024); 69 | 70 | for (var i = 0; i < x.length; i++) { 71 | x[i] = ((i / x.length) - 0.5) * 2; 72 | } 73 | console.log(calcDifference(x, curve)); 74 | --------------------------------------------------------------------------------