Web Audio Playground Max, Osc, and WebSockets

updated 5/17/2014

overview

This fork adds the following features to Chris Wilson’s Web Audio Playground:

  • basic patch load/save capability
  • clipboard copy/paste to get patches in and out of browser
  • OSC control of all parameters using web sockets and a ruby server.

Try it out at: http:zerokidz.com/wap/index.html

For optimum results try Chrome on Mac OS. But it does work in other browsers.

Patch file format is JSON. Patches are reloaded by firing gesture events which created them.

download

Source code: https://github.com/tkzic/WebAudio

files

sub-folder: osctest

Instructions for Osc, Websockets Max/MSP example

Note: You can either run a local web server, using nodeserver.js and index.html – in the WebAudio folder – or use the online version of WAP as described here.

1.  Load WAP in a Google Chrome browser using the following URL: http:zerokidz.com/wap/index.html

2. In WAP, load a patch called: delay-thing.

Note: If the patch doesn’t exist you can paste it in by opening the file osctest/delay-thing.json in a text editor and copying the text. Then click paste in WAP and paste in the text. Then make sure to save it in WAP by typing in the name “delay-thing” and clicking the save-as: button

3. In a terminal window, go to the osctest/ folder and start the server by typing:

ruby ./wapOSCserver.rb

4. In WAP, Press the OSC button – the ruby server should acknowledge with the message: “WebSocket connection open”

5. Open the Max patch: wapOSCtester.maxpat

6. In WAP press the play button on the Oscillator module (you should hear sounds)

7. In the Max patch drag the slider on the left to control the oscillator pitch. You should hear the sound change and see the sliders move in WAP.

Notes on Web Sockets connection:

The html side of the connection is done in js/socketsOSC.js

look at the function: connectOSC() – which gets triggered by the OSC button in index.html

Incoming messages from Max (via Ruby server) are parsed in parseOSCMessage() which figures out how to set appropriate values for the audio objects in the DOM.

There are currently no acknowledgement or error messages being returned (at least I don’t remember doing this)

hardware control of webaudio API

programming

This is a tweak of a demo program by Boris Smus from http://webaudioapi.com

The audio is generated in the web browser using the webaudio API. Oscillator frequency is being controlled by an iPod touch running touchOSC.

A ruby program is running in the background. It starts 2 servers, one to handle Osc messages from the iPod. and a websockets server which passes Osc messages to the web client in the browser, which parses the data and sets oscillator frequency.

local source files in tkzic/web-audio-api/webaudioapi/content/posts/oscillator-ws

instructions

(these are for my local files – source has not been published yet) Please contact me directly for more information about this code. Or have a look at a very similar example at: https://github.com/tkzic/WebAudio

1. run the node webserver in tkzic/

node nodeserver.js

(it will run on localhost port 8081 – for example http://127.0.0.1:8081)

2. In Chrome web browser, run: http://192.168.1.104:8081/web-audio-api/webaudioapi/content/posts/oscillator-ws/index.html

The following screen will appear:

3. From a terminal prompt run this ruby script (in tkzic/web-audio-api/webaudioapi/content/posts/oscillator-ws)

./wapOSCserver.rb

4. In webpage in Chrome, click the sockets button – the ruby server should open a socket connection, also click the play/pause button to start the oscillator

5. In touchOSC point the host to the ip address of the laptop (ie., 192.168.1.104) running on default ports, (out 8000, in 9000)

6. In touchOSC run the ‘simple’ layout and move fader1 to change the pitch of the oscillator

Note: You will probably also want to open the developer javascript console in Chrome to see what is going on.

next step

Need to clean up the ruby server code to handle error conditions, ie., network interruptions, missing files, browser incompatibility, etc.,

 

html5 websockets and ruby

Update 6/2014 – Working examples at Internet sensors projects: https://reactivemusic.net/?p=5859

original post

notes

http://www.html5rocks.com/en/tutorials/websockets/basics/

http://www.websocket.org/echo.html

http://html5demos.com/web-socket

Got some examples running in web sockets (finally). Like with node.js, you can’t access servers from outside, which specify their ip address as localhost – you need to actually set a real ip, even if its a private ip like 192.168.1.20

Anyway I was able to get a ruby websocket server running using em-websocket and also another version using eventmachine.

Local files are in tkzic/websockets

the examples are running a public server at http://zerokidz.com/websockets/index.html

(need to start the server – also in that directory: ./server.rb

There’s also a simple node.js webserver in that folder – but after solving the problem above – apache works just fine.

How do I talk to a client from within a loop using EventMachine?

 

 

Zombie processes in Max

Shell object artifacts.

Today I set up a subpatcher in Max to launch a ruby server, using [aka.shell]. I didn’t realize it was running, so I ran it again – then Max froze, so I force-quit out of it. This left a zombie process in control of the UDP port.

Later I found this command, which identifies all processes on the machine:

# ps -xo pid,ppid,stat,command

Anyway, its probably not a good idea to run servers from shell commands without a way to kill them.

Here’s a screenshot of the sub-patcher which figures out how to run a shell command in the same folder as the patch:

 file

in tkzic/max teaching examples/

ruby-shell-server-trick.maxpat

 

The sound of a new machine

Using internet ping data to control a synthesizer in Max

This project uses ‘ping’ times to about 40 Google domains, like google.ca, google.de, etc., to control pitch and amplitude of a 20 voice droning synthesizer.

Imagine working in a Google control center. A soothing low pitched drone fills the room. Then Suddenly you hear a slowly rising pitch. You check the monitors – Google Paraguay is experiencing network failure. You light a cigarette and wait for things to calm down.

update 2/6/2021

Not using ruby to ping – due to API shutting down. The new version uses the Max [shell] external to ping from the command line.

download

https://github.com/tkzic/internet-sensors

folder: ping

files

main Max patch
  • sound-of-a-new-machine3.maxpat
abstractions and other files

instructions

  • Open the Max patch: sound-of-a-new-machine3.maxpat
  • Turn on audio. Turn up the gain.
  • In the Max patch, click the toggle box to start polling. It may take a minute to hear any sounds, while the oscillators are loading. Increase polling speed to 400 or so if you can’t wait.
  • Another reason you might not hear anything interesting is if the clip threshold is too low. Watch the incoming ping times and set the clip threshold above the average level.
  • Adjust the pitch multiplier to your desired pitch range. It will take some time for all of the oscillators to adjust after a pitch change.
  • If you hear clicks or pops, try reducing the sample rate to 44.1 KHz, or increasing the IO vector size (in Options | Audio Status).

note: Occasionally the server program will time-out when its launched. Try launching again, or edit it and increase the timeout value in [p shellping].


deprecated information for previous version using ruby

The server is a ruby script which handles the http: requests using the Mashape ping-uin API and sends messages to Max using OSC

The synth has a weird clustering drone like effect like some kind of alien life force.

The patch design is kind of embarrassing. Its obvious I forgot how to use [poly~]. Maybe by the time you read this, we’ll have addressed this.  Hey billions of patch cords look cool.

Here’s an example of the Mashape API in curl

curl --include --request GET 'https://igor-zachetly-ping-uin.p.mashape.com/pinguin.php?address=google.ca' \
  --header 'X-Mashape-Authorization: YOUR-MASHAPE-API-KEY'

Here’s a list of Google domains

http://en.wikipedia.org/wiki/List_of_Google_domains

download

https://github.com/tkzic/internet-sensors

folder: ping

files

main Max patch
  • sound-of-a-new-machine2.maxpat
abstractions and other files
  • google.txt (list of domains for [coll] object
ruby
  • domain-ping.rb

ruby gems

install the following ruby gems using: sudo xcrun gem install <gem-name>

  • require ‘osc-ruby’
  • require ‘patron’
  • require ‘json’

authorization

  • Register with mashape http://mashape.com to get an API-key for ping-uin
  • Then edit domain-ping.rb to enter your mashape API-key.

instructions

  • Open the Max patch: sound-of-a-new-machine2.maxpat
  • Turn on audio. Turn up the gain.
  • From a terminal window type the following command
# ./domain-ping.rb


  •  In the Max patch, click the toggle box to start polling. It may take a minute to hear any sounds, while the oscillators are loading. Increase polling speed to 400 or so if you can’t wait.
  • Another reason you might not hear anything interesting is if the clip threshold is too low. Watch the incoming ping times and set the clip threshold above the average level.
  • Adjust the pitch multiplier to your desired pitch range.
  • When you’ve had enough, type <ctrl-c> in the terminal window to stop the server.

note: Occasionally the server program will time-out when its launched. Try launching again, or edit it and increase the timeout value.

 

curl examples

update 11/02/2014 – in process of updating and checking examples – but we know for sure that the Twitter examples are broken.

notes

This post is a collection of many examples of using curl (from a terminal command line) to make API requests. The ones marked with* will run without passwords or api-keys. The responses will generally be in XML, JSON, or HTML

Some of these curl examples will have API keys, user names, and passwords. To run them, you’ll need to replace the keys with your own.

Also, when running from the command line, ampersands ‘&’ will need to be escaped by preceding them with a backslash, like \&

Other characters may need to be escaped, like:

%23 = #

%40 = @

Or you can wrap the entire URL is quotes like this:

curl "dict://dict.org/d:penguin"
tips for finding curl examples

Look in the address bar of your web browser. Copy the entire URL and run it in curl. It will respond with the ‘text’ version of the web page.

displaying JSON on the command line

The respond from curl is raw data. To format JSON data, pipe the output through python, like this:

curl dict://dict.org/d:dog | python -mjson.tool

examples:

dict.org*
curl dict://dict.org/d:antelope
Twitter search (broken)

Twtitter API now requires authentication and will not run from a single curl command, except by using widgets. See this post: https://reactivemusic.net/?p=17428

openweathermap.com*
curl http://api.openweathermap.org/data/2.1/forecast/city/524901

See this post for details: https://reactivemusic.net/?p=6265

vine.com*
curl https://api.vineapp.com/timelines/popular
mashape.com API

Here’s an example of a typical API call which gets the weather in San Francisco. Note I have obscured the API-key.

curl -H "X-Mashape-Authorization: YOUR-MASHAPE-KEY" "https://george-vustrey-weather.p.mashape.com/api.php?_method=getForecasts&location=San%20Francisco"

Here’s the result:

[{"day_of_week":"Wed","high":"63","low":"47","condition":"Mostly Clear"},{"day_of_week":"Thu","high":"66","low":"50","condition":"Partly Cloudy"}]

[Note] more examples in tkzic/mashape

dictionaryapi.com

Here is an example of a request to the Thesaurus API

curl http://www.dictionaryapi.com/api/v1/references/thesaurus/xml/cheese?key=ee2466d2-07a0-40af-b959-abcdeb125f0ca

 

*pandorabots.com

Here are two examples I just got to work using curl

curl -X POST  --data "botid=b0dafd24ee35a477&input=hello" http://www.pandorabots.com/pandora/talk-xml

curl -X POST  --data "botid=b0dafd24ee35a477&input=Where are you?" http://www.pandorabots.com/pandora/talk-xml
Here is the result for the second question
<result status="0" botid="b0dafd24ee35a477" custid="b3422b612633ac87"><input>Where are you?</input><that>I am in the computer at Pandorabots.com.</that></result>
*more pandorabots.com
curl -X POST  --data "botid=b0dafd24ee35a477&input=hello" http://www.pandorabots.com/pandora/talk-xml

curl -X POST  --data "botid=b0dafd24ee35a477&input=Where are you?" http://www.pandorabots.com/pandora/talk-xml

curl -X POST  --data "botid=b0dafd24ee35a477&input=Lets play some music today." http://www.pandorabots.com/pandora/talk-xml
Google speech API (may be broken – need to check the key)

This is an example of the curl command to run from the command line

the test.flac file is located in tkzic/speech – it contains a recording of the phrase “there are turtles wandering through the city”. If you click on the file it will play through audacity.

curl \
  --data-binary @test.flac \
  --header 'Content-type: audio/x-flac; rate=16000' \
  'https://www.google.com/speech-api/v1/recognize?xjerr=1&client=chromium&pfilter=2&lang=en-US&maxresults=6'
cosm.com (may be broken)

Today I was finally able to get this working. Reading a Cosm (Pachube) feed from curl and from Max. Here is an example that works in curl: (replace API-KEY with actual key)

curl http://api.cosm.com/v2/feeds/76490/datastreams/Power.xml?key=API-KEY

You can get JSON responses by leaving off the .xml extension or replacing it with .json

Its critical to use “key=…” not “X-ApiKey=…” like in the cosm documentation, or you will get permission errors from curl and Max.

Youtube.com v3 API

Link to documentation: https://developers.google.com/youtube/v3/docs/search/list

Here is an example (minus the api-key) which searches for videos about cats and returns a JSON response

curl "https://www.googleapis.com/youtube/v3/search?key=API-KEY&part=snippet&q=cats"
google.com custom search API

Use this method to have a custom search which searches the whole web…

http://stackoverflow.com/questions/4082966/google-web-search-api-deprecated-what-now

Here is an example of a search using this method with curl – note the API-KEY is removed

curl "https://www.googleapis.com/customsearch/v1?key=API-KEY&cx=012117491442732664551:egvalbpelhq&q=lectures"
Twitter streaming API (broken)
 google.com simple search API*

Not really applicable to curl, but it shows something.

curl -A Mozilla http://www.google.com/search?q=linux
coastal wind data API (broken 11/2014)
with a specific lat/lon you can get results along the west coast of us - here's san francisco. This query returns all the current time points for SF

curl http://cordc.ucsd.edu/js/COAMPS/query.php?ll=37.78,-122.44\&fmt=json > sf.json 

lets try for santa cruz

curl http://cordc.ucsd.edu/js/COAMPS/query.php?ll=36.99,-122.03\&fmt=json > sc.json

 

spellout.org API*
very cool api that does phonetic spellings - works!!!!

curl http://api.spellout.org/en/convert?text=some%20text\&alphabet=int-icao\&format=json
cosm.com API (PUT request)
This works as of 1/28/2013

curl -v --request PUT --data-binary @./abc.json --header "X-ApiKey: 96PqSh4rj7HzNif3rWms3SUhwaDFGUT0g" http://api.cosm.com/v2/feeds/98281.json

 

Internet sensors projects

overview

A series of projects that use Internet API’s for interactive media projects.

updated 2/14/2021.

Projects have been tested on Max8 and Mac OS Catalina – except where noted.  Other dependencies are are listed on individual project pages.

My goal is to show a variety of methods to get data to and from Max. API’s come and go, as do the libraries that support them.

download

internet-sensors is on Github at:  https://github.com/tkzic/internet-sensors

Each project is in a separate folder.

authorization

Some projects require passwords and API-keys from providers.

For example, for the ‘Twitter streaming API in Max’ project you’ll need to set up a Twitter application from your account to get authorization credentials.

For projects that need authorization usually you’ll just need to modify the patches/source code with your user information – as directed in the instructions.  The API keys embedded in the code will not work unless specifically mentioned, like with the Google speech API.

help

API’s used in the projects change fairly often. So there’s no guarantee they’ll work. If you find problems or have ideas – please post to them to the github repository. Or email me at [email protected].

projects

1. Twitter streaming API in Max (FM, php, curl, geocoding, [aka.speech], Soundflower (optional), Morse code, OSC, data recorder, Twitter v1.1 API, Twitter Apps, Oauth)

https://reactivemusic.net/?p=5786

2. Sending tweets from Max using curl ([sprintf], [aka.shell], xively.com API, zapier.com API, JSON, javascript Twitter v1.1 API, Oauth)

deprecated 2/11/2021 – old project link here: https://reactivemusic.net/?p=5447

3. Send and receive tweets in Max using ruby (ruby, API, JSON, javascript Twitter v1.1 API, OSC, Oauth)

New! – use the project above to send tweets from using a Fisher Price “Little Tikes” piano: https://reactivemusic.net/?p=6993

4. Speech to text in Max (Google speech API, JSON, javascript, sox, Twitter v1.1 API, Oauth)

Note: Send Tweets using speech as well.

https://reactivemusic.net/?p=4690

5. A conversation with a robot in Max (Google speech API, sox, JSON,  pandorabots API, python, [aka.speech]

https://reactivemusic.net/?p=9834

7. Playing bird calls in Max (xeno-canto API, [jit.uldl], [jit.qt.movie])

https://reactivemusic.net/?p=4225

8. Soundcloud API in Max (node.js)

https://reactivemusic.net/?p=20120

 

9. Real time train map using Max and node.js (XML, JSON, OSC, data recorder, web sockets, Irish Rail API)

https://reactivemusic.net/?p=5477

10. stock market music in Max (OSC, netcat,  php, mysql, html, javascript, Yahoo API, linux)

…updates in progress…

https://reactivemusic.net/?p=12029

11. Using weather forecast data to drive weather sounds in Pure Data (ruby, OSC, JSON, openweathermap API, “Designing Sound” by Andy Farnell)

https://reactivemusic.net/?p=5846

… updates in progress…

12. Using ping times to control oscilators in Max (Mashape ping-uin API, ruby, OSC, JSON)

https://reactivemusic.net/?p=5945

13. Spotify Segment analysis player – sonification of audio analysis data from Spotify (echo nest) API, node,  Max/MSP)

https://reactivemusic.net/?p=20096

14. Quadcopter AR_drone – Fly a quadcopter using Max – with streaming Web video. ( node.js, AR_drone, Google Chrome, Osc, Max/MSP)

deprecated 2/14/2021 – old project link: https://reactivemusic.net/?p=6635

15. Adding markers to Google Maps in Max – ( node.js, ruby, Google Chrome, Osc, Max/MSP, websockets, Google Maps API, Jquery, javascript)

deprecated 2/14/2021 – old project link: https://reactivemusic.net/?p=11412

16. Max data recorder –  Record and play back streams of data simultaneously at various rates

https://reactivemusic.net/?p=8053

17. MBTA bus data in Max –  Sonification of Mass Ave buses, from Harvard to Dudley

… updates in progress…

https://reactivemusic.net/?p=17524

Screen Shot 2014-11-11 at 3.26.16 PM

 

Using wind forecast data to generate wind sounds with Pd

This project receives wind data from the U.S. Coastal Observing Research and Development Center (CORDC) at Scripps Institute of Oceanography  the openweathermap.org API

http://cordc.ucsd.edu/projects/models/coamps/api/

http://openweathermap.org/API

It uses the data to set the ‘wind speed’ of Andy Farnell’s wind sound patches from “Designing Sound”

http://aspress.co.uk/sd/index.php

Error 4/26/2014

Getting a parsing error on the ruby script. Will be debugging shortly!

<span style="color: rgb(0, 0, 0);">/Users/tkzic/.rvm/gems/ruby-2.0.0-p353@global/gems/json-1.8.1/lib/json/common.rb:155:in `initialize': A JSON text must at least contain two octets! (JSON::ParserError)</span>
<span style="color: rgb(0, 0, 0);">from /Users/tkzic/.rvm/gems/ruby-2.0.0-p353@global/gems/json-1.8.1/lib/json/common.rb:155:in `new'</span>
<span style="color: rgb(0, 0, 0);">from /Users/tkzic/.rvm/gems/ruby-2.0.0-p353@global/gems/json-1.8.1/lib/json/common.rb:155:in `parse'</span>
<span style="color: rgb(0, 0, 0);">from ./wind-open-forecast.rb:92:in `&lt;main&gt;'</span>

———————————————–

The http: requests are managed by a ruby server script and sent via OSC to Pure Data.

Two of Andy Farnell’s patches are also running (with very slight mods): wind4a.pd, and thunder4a.pd

From pd, you can select which city to get data from, and control the rate at which the data is replayed from the ruby server. The forecast cycle is about 3 days long.

From the pd patch you can select the rate of data playback, and select which city to use for data (Santa Cruz or San Diego).

Note: the wind speed expected by Andy Farnell’s wind patch is between 0 and about 0.7

download

https://github.com/tkzic/internet-sensors

folder: pd-weather

files

main Pd patches
  • wind-open-machine.pd
  • thunder4a.pd
  • wind4a.pd
pd abstractions

designingSound/ folder:

Add this folder to the path list in Pd before the system files because the distance.pd abstraction has the same name as a system file used for map distances.

  • distance.pd
  • fcpan.pd
  • strike-pattern.pd
  • strike-sound.pd
  • udly.pd
ruby
  • wind-open-forecast.rb
required gems include:
  • osc-ruby
  • patron
  • json

authorization

  • none required

instructions

1. Open all three pd patches
  • wind-open-machine.pd
  • thunder4a.pd
  • wind4a.pd
2. Turn audio on
3. start the ruby script from a terminal window by typing

./wind-open-forecast.rb
(NOTE: Sometimes the ruby script will time-out when you first launch it. Just run it again.)

4. You can tweak various parameters to scale the effect of the wind data on the sounds

revision history

5/19/2014

currently getting this error in the ruby server – need to rewrite:

  • update 3-25-2013 If you are running this  project and getting errors from the ruby script –   CORDC is not producing wind data – so please use this workaround – which uses the openweathermap.org API

 

sending Tweets from Max using ruby, xively.com, and zapier.com

This is a ruby version of the Max tweetCurl5 patch (which tweets via xively.com) described here:

https://reactivemusic.net/?p=5447

In this version, the Max patch communicates via OSC to a background server running in ruby. An advantage of this method is that both the patch and the server are  compact and easy to understand. The Max patch does things in a Max way. And likewise with the ruby script.

Here’s a screen shot of the Max patch:

 files

Max

  • ruby-max-tweet.maxpat

ruby

  • ruby-max-tweet.rb

The ruby script requires installation of the following gems

  • patron
  • osc-ruby

For example:

# gem install patron

authorization

  • The xively.com feed id and api-key are embedded in ruby script
  • To get this project to work you’ll need a Twitter account. And you’ll need to set up a device (feed) at xively.com and a ‘zap’ at zapier.com as directed in this post. It explains how to send tweets using triggers. https://reactivemusic.net/?p=6903

instructions

  • Open the Max patch: ruby-max-tweet
  • In a terminal window run the ruby script:
  • # ./ruby-max-tweet.rb
  • In the Max patch, type in a tweet. Press the green button to send.
  • When you have Tweeted enough, end the ruby server program by typing <ctrl-c>

download

The files for this project can be downloaded from the intenet-sensors archive at github

https://github.com/tkzic/internet-sensors