Wavepot dot com
June 18, 2014 12:01 PM   Subscribe

Wavepot is an online waveform editor and basic DAW programmable in javascript. Choose a project on the right hand side to get started tweaking. Simple Sine is the most basic example, and projects like "ice cream" and "late morning" have complex patterns and bassline examples.
posted by boo_radley (22 comments total) 47 users marked this as a favorite
OK this is cool. What's the range of t?
posted by rouftop at 12:09 PM on June 18, 2014

I was playing with this a bunch yesterday. I believe t is the count of measures and it just goes up and up and fractional numbers represent the fraction of the measure that has passed.
posted by thetruthisjustalie at 12:11 PM on June 18, 2014

t is time and is thus ever increasing.
posted by boo_radley at 12:12 PM on June 18, 2014

ah this is so cool! I mean, music is math and computers do math so this makes perfect sense, but it's so incredible to see it laid out like this!
posted by rebent at 12:16 PM on June 18, 2014 [1 favorite]

Here's something similar. It uses ActionScript (Flash scripting language) instead of JavaScript. The examples give some nice uses of shifting (>>) and bit masking.

The nice thing about that site is that it updates your URL with the function, so you can send people links to what you've created, like this example of a robot having gastric distress.
posted by benito.strauss at 12:20 PM on June 18, 2014 [1 favorite]

If you dig this, also see Max and Csound.
posted by escape from the potato planet at 12:52 PM on June 18, 2014

Whatever you do, don't change Math.sin to Math.tan with your volume turned up to see what happens. Not that I did anything like that.
posted by OverlappingElvis at 1:04 PM on June 18, 2014 [4 favorites]

Math.tan? More like Math.burn.
posted by benito.strauss at 1:12 PM on June 18, 2014 [2 favorites]

Your speakers will go off on a tangent
posted by iotic at 1:32 PM on June 18, 2014 [3 favorites]

Since there isn't any documentation, here's what I've been able to figure out...

(this isn't going to help you much unless you have a background in sound synthesis)

Press Ctrl+Enter to start or stop playback.

dsp() is your main function. It gets called 48,000 times per second, and receives one argument, t, which is the time (in seconds) since playback began. It should return the amplitude of the output waveform for that 1/48,000 of a second (i.e., sample), as a value between 1 and −1.

To create a composition with multiple parts (e.g., a drum part and a synth part), simply return the sum of the amplitudes for each part. For example, from the bottom of the "icecream" example:

return 0.7 * (
0.9 * synth
+ kick
+ 0.12 * hat

Each part is multiplied by a scaling factor, to adjust its amplitude relative to the other parts (and then the whole thing is multiplied by 0.7 to adjust the overall amplitude).

Simple example, putting it all together.
posted by escape from the potato planet at 1:42 PM on June 18, 2014 [6 favorites]

Wow, this is cool. Falling down a rabbit hole with Processing has finally got me learning some actual java through Code Academy and this just makes it more fun.

As a side question, how do things like this get built from the ground up? I mean, is it basically that java is a syntax and then there's a library of functions to call for any given build? How do those libraries get built in the first place?
posted by klangklangston at 2:23 PM on June 18, 2014

This is incredibly cool stuf.

I've been writing blocks and patches for Patchblocks and thinking about moving over to VST plugins instead. If I could process audio streams with this, rather than synthesizing them from scratch, I'd be all over it.
posted by Foosnark at 2:28 PM on June 18, 2014

JavaScript, which has nothing to do with Java, is a programming language.

Programming languages allow you to create various kinds of abstractions, which are sometimes reusable. A very simple example is a function:

function average( x, y ) {
return( x + y ) / 2;

This (contrived) example can be reused in any project where you need the ability to easily average two numbers, and could be considered a very simple library.

But you can aggregate simple abstractions like this to create much larger, more complex, and more flexible abstractions. For example, you might build on this humble beginning to create a library for doing statistics, which might include dozens of functions, plus other elements (standardized data structures, utility functions, tools for rendering the computed data in various human-friendly formats, etc.).

A JavaScript library is just a collection of JavaScript code that's generalized enough to be dropped into any random project and reused. The only thing that distinguishes a library from any other piece of code is the intentions of its creators and users. The machine itself doesn't recognize any distinction between libraries and so-called "client code" (the code that invokes the library).

So, to answer your question: libraries get created by programmers who recognize that they've been solving the same problem over and over in their various programs, get tired of reinventing the wheel, and decide to write a solution to the problem that's designed to fit cleanly into any project that needs to solve that problem.
posted by escape from the potato planet at 2:44 PM on June 18, 2014 [3 favorites]

Also: while this app does use several libraries (as almost any significant app does), what ultimately allows it to generate sound is something different—an API, or application programming interface. To explain:

A well designed computer system consists of many discrete components, like departments in a company, each responsible for a specific and clearly delineated set of tasks.

Like departments in a company, those components need to be able to communicate with each other. The agreed-upon channels of communication are what constitute the API. If you think of the various components/departments as being separated by solid walls, then an API is like a set of windows in a wall, through which two departments can pass information and requests—one window for retrieving customer records, one for submitting requisition requests, one for filing job postings, etc. (These "windows" often take the form of function calls.)

The term "API" can refer to both a standards document—which lists the set of windows in that particular API, and defines how programmers should communicate with them—and the actual implementations, or realizations, of that standard in the real world. It's common to gloss between the two senses of the term.

In the simple example above, the API (in the standards-document sense) would be something like "if you want to calculate an average, call the average() function and pass two numbers in; expect to get a single number as the return value". In reality, APIs are much more formal and pedantic than this, but this is the basic idea.

JavaScript is traditionally run within a browser, and so there's an especially thick and windowless wall between your JavaScript program and the rest of the computer (such as the file system, the sound card, and any other programs that might be running on the computer). JavaScript basically runs inside of an insulated bubble, with very limited access to anything outside of its own little browser window.

But that's changing. Newer browsers support a variety of emerging and experimental new APIs—windows through the bubble—which allow JavaScript to interact with these other components of the broader system.

This raises an important point: APIs can exist between different parts of an application (for example, one component of a JavaScript app talking to another component of the same app, with both components written in JavaScript), or between different systems or applications (for example, JavaScript code communicating with the browser to request control of the computer's audio system).

*deeeeeeep breath*

My actual point is this: the emerging browser API that allows JavaScript to access the noisemaking bits of the broader computer is called the Web Audio API. It's a standard that says "hey browser makers, build your JavaScript engine to support these function calls according to these specifications; then people can write JavaScript code that calls these functions, and it'll just work no matter what browser it's run in". Sort of like how you can buy light bulbs manufactured by dozens of different companies, but they'll all work in your lamp, because both the light bulb manufacturers (you, the JavaScript coder) and the lamp manufacturer (the browser makers) followed the same standard.

So, while this app probably communicates with the Web Audio API via a library, which was written to streamline common types of interaction with the Web Audio API, the library isn't the necessary bit. It's just a convenience for the programmer. It's the API that lets the app reach through the bubble and interact with the audio system.

I could go on, but this is probably way more information than you wanted :)
posted by escape from the potato planet at 4:03 PM on June 18, 2014 [6 favorites]

One more thing, and then I'll shut up:

Foosnark: If I could process audio streams with this, rather than synthesizing them from scratch, I'd be all over it.

I'm pretty sure SuperCollider will let you use any arbitrary audio stream as input. Probably Max and Csound as well.
posted by escape from the potato planet at 4:25 PM on June 18, 2014 [1 favorite]

If you enjoy this stuff, you should watch substack's Beep Boop talk where he programs music on stage.
posted by yaymukund at 5:12 PM on June 18, 2014 [1 favorite]

this is probably way more information than you wanted

Actually, no. You can go on forever if you like. Fascinating.
posted by Steely-eyed Missile Man at 5:13 PM on June 18, 2014

This is amazing. Less slick, but completely open source is the aforementioned insanely-prolific substack's code-music-studio, in case you want to see how to get some excellent synths like this in your own project.
posted by ignignokt at 5:32 PM on June 18, 2014

oh awesome it responds to changes in the code while playing! well, after a short delay after you stop typing, of course, unless there's an error in which case it keeps doing what it was doing until you enter something valid! for some this is extra super cool to me.

this seems like a *brilliant* way to learn dsp programming, which is something i've sort of been meaning to do for a long time
posted by atoxyl at 8:45 PM on June 18, 2014

My favorite thing along these lines is Andrew Sorenson's Impromptu, which is in the process of being rewritten and made portable (Impromptu is OS X only), and called Extempore. It amazes me this kind of power can be done in the browser, but I suspect well-written native code can do more -- but haven't tested either systems' limits.
posted by dylanjames at 9:21 PM on June 18, 2014

Try this:

function dsp(t) {
return 1 * Math.sin(Math.tan(Math.pow(t,2)*250));
posted by Veritron at 1:04 AM on June 19, 2014 [2 favorites]

I tried it, and I enjoyed it, but what do I do about the trans-dimensional being that it summoned? He wants breakfast and I'm out of trans-dimensional milk!
posted by benito.strauss at 10:34 AM on June 19, 2014

« Older Grantland Tackles Boardgames   |   Doctor. Newer »

This thread has been archived and is closed to new comments