{"id":1140,"date":"2013-07-20T21:45:29","date_gmt":"2013-07-21T03:45:29","guid":{"rendered":"http:\/\/cbateman.com\/blog\/?p=1140"},"modified":"2014-04-19T01:40:46","modified_gmt":"2014-04-19T06:40:46","slug":"a-web-audio-api-toy","status":"publish","type":"post","link":"https:\/\/cbateman.com\/blog\/a-web-audio-api-toy\/","title":{"rendered":"A Web Audio API Toy"},"content":{"rendered":"<p>Access it here: <a href=\"\/demos\/AudioTrackr\/\">AudioTrackr<\/a>.<\/p>\r\n\r\n<p>I built a fun little thingy with the Web Audio API. It visualizes the frequency levels and waveform of individual tracks in various songs. It was born out of a desire to stress test the Audio API. Turns out it&#8217;s pretty snappy (the slow part, as usual, is just drawing on the canvas).<\/p>\r\n<p><strong>Compatibility<\/strong>: Chrome, Firefox Aurora (24+), and iOS 6+. Unfortunately, Firefox and iOS will load a bit slowly, due to their (current) lack of support for createMediaElementSource (see below). Also, iOS is pretty finicky, so try reloading if it doesn&#8217;t work. It would work in Opera 15, but I&#8217;m only using mp3 files. Safari on Mac has an issue I haven&#8217;t been able to resolve yet.<\/p>\r\n<p>Oh, and I built it with <a href=\"http:\/\/angularjs.org\/\">Angular<\/a>, which I don&#8217;t have much experience with, so I&#8217;m sure I messed it up. I tried to keep as much as I could out of the Angular code (seemed to improve performance a bit to not have everything tied to Angular&#8217;s scope). If you have any suggestions for improvement, please leave me a comment.<\/p>\r\n<p>Here are a few takeways:<\/p>\r\n<ul>\r\n <li>With the Web Audio API, you typically need to download an entire audio file and then decode the entire thing before you can start playing it. However, there&#8217;s this cool new thing called <a href=\"http:\/\/updates.html5rocks.com\/2012\/02\/HTML5-audio-and-the-Web-Audio-API-are-BFFs\">createMediaElementSource<\/a>, which <a href=\"https:\/\/dvcs.w3.org\/hg\/audio\/raw-file\/tip\/webaudio\/webrtc-integration.html\">came out of WebRTC<\/a>. It allows you to plug an HTML5 &lt;audio&gt; element into the API &mdash; which means you can take advantage of the element&#8217;s combined buffering\/streaming\/decoding capabilities. This is awesome, because it means I can start playing multiple files almost right away, instead of waiting forever for all of them to download and decode.<\/li>\r\n <li>Speaking of which, I had to set up some extra subdomains to serve the files from, since browsers will only allow a <a href=\"http:\/\/www.browserscope.org\/?category=network\">certain number<\/a> of simultaneous HTTP connections to a single hostname. And if those connections happen to be audio files that the browser started and then paused downloading &#8211; waiting to see if you&#8217;re actually going to play them &#8211; you&#8217;re in big trouble because it will never start downloading the rest of the files.<\/li>\r\n <li>iOS will only play one Audio element at a time. And there&#8217;s no good way to detect that (other than to actually try it).<\/li>\r\n <li>iOS decodes audio buffers much faster than my quad-core desktop computer (good thing we&#8217;re using &lt;audio&gt; on the dekstop).<\/li>\r\n <li>The API has changed since iOS first implemented it. Thankfully <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web_Audio_API\/Porting_webkitAudioContext_code_to_standards_based_AudioContext\">Mozilla is on top of things<\/a>.<\/li>\r\n <li>It&#8217;s really difficult to find songs released with individual tracks\/stems. So thanks to <a href=\"http:\/\/www.wearephoenix.com\/\">Phoenix<\/a> and <a href=\"http:\/\/wildlifectrl.com\/\">Wildlife Control<\/a> for being awesome (oh and guess what &mdash; Wildlife Control <a href=\"http:\/\/wildlifecontrol.tumblr.com\/post\/14266142693\/analog-or-digital-video\">can write JavaScript too<\/a>). If you know any songs I should add, let me know!<\/li>\r\n <li>Feel free to <a href=\"https:\/\/github.com\/chrisbateman\/Audio-Trackr\">fork it on github<\/a> &mdash; you could add mute\/solo buttons for each track!<\/li>\r\n <li>Thanks to <a href=\"http:\/\/www.kevincennis.com\/mix\/\">Mix.js<\/a> for inspiration.<\/li>\r\n<\/ul>\r\n\r\n<p><a href=\"\/demos\/AudioTrackr\/\">Check it out here.<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Access it here: AudioTrackr. I built a fun little thingy with the Web Audio API. It visualizes the frequency levels and waveform of individual tracks in various songs. It was born out of a desire to stress test the Audio API. Turns out it&#8217;s pretty snappy (the slow part, as usual, is just drawing on the canvas). Compatibility: Chrome, Firefox&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1140","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/posts\/1140"}],"collection":[{"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/comments?post=1140"}],"version-history":[{"count":37,"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/posts\/1140\/revisions"}],"predecessor-version":[{"id":1294,"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/posts\/1140\/revisions\/1294"}],"wp:attachment":[{"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/media?parent=1140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/categories?post=1140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cbateman.com\/blog\/wp-json\/wp\/v2\/tags?post=1140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}