├── .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 |
31 |
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | - `ws1 = (x) -> (x + 1) * 0.5`
14 | - `ws2 = (x) -> 1 - ((x + 1) * 0.5)`
15 |
16 | 
17 |
18 | ### Plot
19 |
20 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | `ws = (x) -> (x < 0) ? 1 : 0`
14 |
15 | 
16 |
17 | ### Plot
18 |
19 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | `ws1 = (x) -> (x != 0) ? 1 : 0`
14 |
15 | _ws2 is used to provide stability the output._
16 |
17 | 
18 |
19 | ### Plot
20 |
21 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | `ws = (x) -> (x > 0) ? 1 : 0`
14 |
15 | 
16 |
17 | ### Plot
18 |
19 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | `ws = (x) -> (x >= 0) ? 1 : 0`
14 |
15 | 
16 |
17 | ### Plot
18 |
19 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | `ws = (x) -> (x == 0) ? 1 : 0`
14 |
15 | _ws2 is used to provide stability the output._
16 |
17 | 
18 |
19 | ### Plot
20 |
21 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | `ws = (x) -> x == 0 ? 1 : (1 / (x * MAX_VALUE))`
14 |
15 | 
16 |
17 | ### Plot
18 |
19 | _Green line represents ideal computed values._
20 |
21 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | `ws = (x) -> (x == 0) ? 0 : (x < 0) ? -1 : 1`
14 |
15 | 
16 |
17 | ### Plot
18 |
19 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
10 |
11 | ### WaveShape
12 |
13 | - `ws1 = (x) -> (x > 0) ? 1 : 0`
14 | - `ws2 = (x) -> (x < 0) ? 1 : 0`
15 |
16 | 
17 |
18 | ### Plot
19 |
20 | 
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 | 
10 |
11 | ### Plot
12 |
13 | 
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 | 
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 | 
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 |
--------------------------------------------------------------------------------