UNPKG

genish.js

Version:
115 lines (91 loc) 5.29 kB
<!DOCTYPE html> <html lang="en"> <head> <!-- Basic Page Needs –––––––––––––––––––––––––––––––––––––––––––––––––– --> <meta charset="utf-8"> <title>genish.js</title> <meta name="description" content="A JS library for generating per-sample audio callbacks."> <meta name="author" content="Charlie Roberts"> <!-- Mobile Specific Metas –––––––––––––––––––––––––––––––––––––––––––––––––– --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- FONT –––––––––––––––––––––––––––––––––––––––––––––––––– --> <link href="//fonts.googleapis.com/css?family=Raleway:400,300,600" rel="stylesheet" type="text/css"> <!-- CSS –––––––––––––––––––––––––––––––––––––––––––––––––– --> <link rel="stylesheet" href="css/normalize.css"> <link rel="stylesheet" href="css/skeleton.css"> <!-- Favicon –––––––––––––––––––––––––––––––––––––––––––––––––– <link rel="icon" type="image/png" href="images/favicon.png"> --> <script src="./node_modules/codemirror/lib/codemirror.js"></script> <link rel="stylesheet" href="./node_modules/codemirror/lib/codemirror.css"> <link rel="stylesheet" href="./node_modules/codemirror/theme/neo.css"> <script src="./node_modules/codemirror/mode/javascript/javascript.js"></script> <style> h5 { color: #666 } button { text-transform: none } #codemirror, #codemirror2 { border: 1px solid #ccc; margin-bottom:1em } </style> <script> const inputcode = `const baseFrequency = 80, c2m = 1.4, index = .95 // create our oscillator for modulation let modulator = cycle( mul( baseFrequency, c2m ) ) // scale amplitude based on index value, re-assign modulator = mul( modulator, mul( baseFrequency, index ) ) // create carrier oscillator and modulate frequency const carrier = cycle( add( baseFrequency, modulator ) ) // create an exponential decay lasting eight seconds const env = decay( gen.samplerate * 8 ) // multiply carrier output by envelope and play play( mul( carrier, env ) )` window.onload = function() { cm = CodeMirror( document.querySelector('#codemirror'), { mode: 'javascript', value: inputcode, autofocus: false, theme:'neo' }) cm.setSize( null, '28em' ) } </script> </head> <body> <!-- Primary Page Layout –––––––––––––––––––––––––––––––––––––––––––––––––– --> <div class="container"> <div class="row"> <div class="two-thirds column" style="margin-top: 15%"> <h2>genish.js</h2> <h5>one sample at a time, please.</h5> <a href="./playground/index.html"><button>playground</button></a> <a href="./docs/index.html"><button>docs</button></a> <a href="./tutorial/index.html"><button>tutorial</button></a> <a href="./jsdsp.html"><button>jsdsp</button></a> <a href="https://github.com/charlieroberts/genish.js"><button>github</button></a> <p>genish.js is a library to help develop optimized audio callbacks employing per-sample processing techniques. This enables signal processing that is not possible using buffers, for example:</p> <ul> <li>chaotic oscillators</li> <li>fm feedback</li> <li>feedback delay networks</li> <li>physical modeling</li> <li>audio-rate modulation of scheduling</li> </ul> <p>In our opinion per-sample processing is also easier to reason about than processing in blocks of hundreds of samples at a time. Process a sample in unit generator <code>A</code>, then feed it into unit generator <code>B</code>. And then feed the result back into unit generator <code>A</code> to influence the next sample if you want.</p> <p>The trade-off is efficiency, which is especially important in a dynamic runtime environment like what JavaScript offers. Accordingly, genish takes the audio graphs you write and creates an optimized callback from them. The code generation step minimizes branches, consolidates memory for the audio callback into a single heap, and removes any traversal of scope / prototype in the callback. Below is an example of a genish.js graph to create a two-operator FM gong sound (taken from <a href="./tutorial/index.html">the genish tutorial</a>).</p> <div id='codemirror'></div> <p>genish.js is inspired by the gen~ extension for <a href="https://cycling74.com/products/max/">Max/MSP</a>. </div> </div> </div> <!-- End Document –––––––––––––––––––––––––––––––––––––––––––––––––– --> </body> </html>