From 4f90ac009b7e8710f0caaaaa0b7665d6d33cbfb8 Mon Sep 17 00:00:00 2001 From: Endel Dreyer Date: Sun, 9 Dec 2012 02:29:52 -0200 Subject: [PATCH 1/3] Add microphone support, using new WebKit Audio API. Modify and document out new Dancer#load interface, which must accept only plain objects right now, since there are already three ways of loading (Audio element / src attribute / Microphone Input). Also added an example of microphone using FFT on examples/fft-microphone. --- README.md | 11 +- dancer.js | 82 +++--- examples/audio_element/js/player.js | 2 +- .../css/League_Gothic-webfont.eot | Bin 0 -> 45426 bytes .../css/League_Gothic-webfont.svg | 235 ++++++++++++++++++ .../css/League_Gothic-webfont.ttf | Bin 0 -> 45212 bytes .../css/League_Gothic-webfont.woff | Bin 0 -> 23940 bytes examples/fft-microphone/css/dancer.css | 113 +++++++++ .../fft-microphone/images/particle_blue.png | Bin 0 -> 640 bytes .../fft-microphone/images/particle_green.png | Bin 0 -> 707 bytes .../fft-microphone/images/particle_orange.png | Bin 0 -> 694 bytes .../fft-microphone/images/particle_pink.png | Bin 0 -> 636 bytes .../fft-microphone/images/particle_white.png | Bin 0 -> 652 bytes .../fft-microphone/images/particle_yellow.png | Bin 0 -> 627 bytes examples/fft-microphone/index.html | 37 +++ examples/fft-microphone/js/player.js | 84 +++++++ src/adapterWebkit.js | 34 ++- src/dancer.js | 28 ++- src/support.js | 12 +- 19 files changed, 585 insertions(+), 53 deletions(-) create mode 100755 examples/fft-microphone/css/League_Gothic-webfont.eot create mode 100755 examples/fft-microphone/css/League_Gothic-webfont.svg create mode 100755 examples/fft-microphone/css/League_Gothic-webfont.ttf create mode 100755 examples/fft-microphone/css/League_Gothic-webfont.woff create mode 100644 examples/fft-microphone/css/dancer.css create mode 100644 examples/fft-microphone/images/particle_blue.png create mode 100644 examples/fft-microphone/images/particle_green.png create mode 100644 examples/fft-microphone/images/particle_orange.png create mode 100755 examples/fft-microphone/images/particle_pink.png create mode 100644 examples/fft-microphone/images/particle_white.png create mode 100644 examples/fft-microphone/images/particle_yellow.png create mode 100644 examples/fft-microphone/index.html create mode 100644 examples/fft-microphone/js/player.js diff --git a/README.md b/README.md index a81244a..e53fb27 100644 --- a/README.md +++ b/README.md @@ -28,16 +28,19 @@ Dancer Instance Methods // Using an audio object var a = new Audio(); a.src = 'somesong.mp3'; - dancer.load( a ); + dancer.load({ audio: a }); // Using an audio element on the page - dancer.load( document.getElementsByTagName('audio')[0] ); + dancer.load({ audio: document.getElementsByTagName('audio')[0] }); // Using a config object and you only have one encoding dancer.load({ src: 'somesong.mp3' }); // Using a config object, and you have an ogg and mp3 version dancer.load({ src: 'somesong', codecs: [ 'ogg', 'mp3' ]}); + + // Using microphone input (webkit only) + dancer.load({ microphone: true }); ``` ### Controls @@ -54,7 +57,7 @@ All controls return `this`. If provided an audio element as the source, one can * `getTime()` returns the current time. * `getProgress()` returns the downloading progress as a float from 0 to 1. * `getWaveform()` returns the waveform data array (Float32Array(1024)) -* `getSpectrum()` returns the frequency data array (Float32Array(512)). +* `getSpectrum()` returns the frequency data array (Float32Array(512)). * `getFrequency( freq [, endFreq ] )` returns the magnitude of a frequency or average over a range of frequencies. * `isLoaded()` returns a boolean value for the dancer instance's song load state. * `isPlaying()` returns a boolean value indicating whether the dancer instance's song is currently playing or not. @@ -176,7 +179,7 @@ Dependencies Extending/Plugins --- -You can extend the Dancer prototype by calling the static method `addPlugin( name, fn )`, which extends the Dancer prototype. A Dancer instance then can call the function provided in its context and subscribe to a preexisting event like `update`, or make your own. Look in the `plugins/` directory for examples. +You can extend the Dancer prototype by calling the static method `addPlugin( name, fn )`, which extends the Dancer prototype. A Dancer instance then can call the function provided in its context and subscribe to a preexisting event like `update`, or make your own. Look in the `plugins/` directory for examples. Development --- diff --git a/dancer.js b/dancer.js index 847fdba..19464db 100644 --- a/dancer.js +++ b/dancer.js @@ -20,24 +20,36 @@ var path; // Loading an Audio element - if ( source instanceof HTMLElement ) { - this.source = source; + if (source.audio) { + this.source = source.audio; if ( Dancer.isSupported() === 'flash' ) { - this.source = { src: Dancer._getMP3SrcFromAudio( source ) }; + this.source = { src: Dancer._getMP3SrcFromAudio( source.audio ) }; } + this.loadAudioAdapter(this.source); + // Loading an object with src, [codecs] - } else { - this.source = window.Audio ? new Audio() : {}; - this.source.src = Dancer._makeSupportedPath( source.src, source.codecs ); + } else if (source.src) { + this.source = window.Audio ? new Audio() : {}; + this.source.src = Dancer._makeSupportedPath( source.src, source.codecs ); + this.loadAudioAdapter(this.source); + + // Request user audio + } else if (source.microphone) { + navigator.getUserMedia({audio: true}, this._userMediaCallback, function(e) { + console.log("Unsupported.") + }); + this.source = source; } - this.audio = this.audioAdapter.load( this.source ); return this; }, - /* Controls */ + loadAudioAdapter: function(source) { + this.audio = this.audioAdapter.load( source ); + }, + /* Controls */ play : function () { this.audioAdapter.play(); return this; @@ -195,7 +207,11 @@ window.Dancer = Dancer; })(); + (function ( Dancer ) { + // Avoid browser-specific prefixes. + window.AudioContext = window.AudioContext || window.webkitAudioContext; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; var CODECS = { 'mp3' : 'audio/mpeg;', @@ -206,7 +222,6 @@ audioEl = document.createElement( 'audio' ); Dancer.options = {}; - Dancer.setOptions = function ( o ) { for ( var option in o ) { if ( o.hasOwnProperty( option ) ) { @@ -256,6 +271,7 @@ }; Dancer._getAdapter = function ( instance ) { + Dancer.instance = instance; switch ( Dancer.isSupported() ) { case 'webaudio': return new Dancer.adapters.webkit( instance ); @@ -277,6 +293,13 @@ return null; }; + Dancer.prototype._userMediaCallback = function(stream) { + var context = Dancer.instance.audioAdapter.context; + input = context.createMediaStreamSource(stream); + input.connect(context.destination); + Dancer.instance.loadAudioAdapter(input); + } + // Browser detection is lame, but Safari 6 has Web Audio API, // but does not support processing audio from a Media Element Source // https://gist.github.com/3265344 @@ -290,6 +313,7 @@ })( window.Dancer ); + (function ( undefined ) { var Kick = function ( dancer, o ) { o = o || {}; @@ -309,7 +333,7 @@ }; Kick.prototype = { - on : function () { + on : function () { this.isOn = true; return this; }, @@ -732,9 +756,9 @@ })(); -/* +/* * DSP.js - a comprehensive digital signal processing library for javascript - * + * * Created by Corban Brook on 2010-01-01. * Copyright 2010 Corban Brook. All rights reserved. * @@ -770,7 +794,7 @@ function FourierTransform(bufferSize, sampleRate) { imag = this.imag, bSi = 2 / this.bufferSize, sqrt = Math.sqrt, - rval, + rval, ival, mag; @@ -800,7 +824,7 @@ function FourierTransform(bufferSize, sampleRate) { */ function FFT(bufferSize, sampleRate) { FourierTransform.call(this, bufferSize, sampleRate); - + this.reverseTable = new Uint32Array(bufferSize); var limit = 1; @@ -870,7 +894,7 @@ FFT.prototype.forward = function(buffer) { //phaseShiftStepImag = Math.sin(-Math.PI/halfSize); phaseShiftStepReal = cosTable[halfSize]; phaseShiftStepImag = sinTable[halfSize]; - + currentPhaseShiftReal = 1; currentPhaseShiftImag = 0; @@ -941,7 +965,7 @@ var FlashDetect = new function(){ ]; /** * Extract the ActiveX version of the plugin. - * + * * @param {Object} The flash ActiveX object. * @type String */ @@ -954,7 +978,7 @@ var FlashDetect = new function(){ }; /** * Try and retrieve an ActiveX object having a specified name. - * + * * @param {String} name The ActiveX object name lookup. * @return One of ActiveX object or a simple object having an attribute of activeXError with a value of true. * @type Object @@ -970,8 +994,8 @@ var FlashDetect = new function(){ }; /** * Parse an ActiveX $version string into an object. - * - * @param {String} str The ActiveX Object GetVariable($version) return value. + * + * @param {String} str The ActiveX Object GetVariable($version) return value. * @return An object having raw, major, minor, revision and revisionStr attributes. * @type Object */ @@ -987,7 +1011,7 @@ var FlashDetect = new function(){ }; /** * Parse a standard enabledPlugin.description into an object. - * + * * @param {String} str The enabledPlugin.description value. * @return An object having raw, major, minor, revision and revisionStr attributes. * @type Object @@ -999,14 +1023,14 @@ var FlashDetect = new function(){ return { "raw":str, "major":parseInt(majorMinor[0], 10), - "minor":parseInt(majorMinor[1], 10), + "minor":parseInt(majorMinor[1], 10), "revisionStr":revisionStr, "revision":parseRevisionStrToInt(revisionStr) }; }; /** * Parse the plugin revision string into an integer. - * + * * @param {String} The revision in string format. * @type Number */ @@ -1015,7 +1039,7 @@ var FlashDetect = new function(){ }; /** * Is the major version greater than or equal to a specified version. - * + * * @param {Number} version The minimum required major version. * @type Boolean */ @@ -1024,7 +1048,7 @@ var FlashDetect = new function(){ }; /** * Is the minor version greater than or equal to a specified version. - * + * * @param {Number} version The minimum required minor version. * @type Boolean */ @@ -1033,7 +1057,7 @@ var FlashDetect = new function(){ }; /** * Is the revision version greater than or equal to a specified version. - * + * * @param {Number} version The minimum required revision version. * @type Boolean */ @@ -1042,7 +1066,7 @@ var FlashDetect = new function(){ }; /** * Is the version greater than or equal to a specified major, minor and revision. - * + * * @param {Number} major The minimum required major version. * @param {Number} (Optional) minor The minimum required minor version. * @param {Number} (Optional) revision The minimum required revision version. @@ -1075,7 +1099,7 @@ var FlashDetect = new function(){ var versionObj = parseStandardVersion(version); self.raw = versionObj.raw; self.major = versionObj.major; - self.minor = versionObj.minor; + self.minor = versionObj.minor; self.revisionStr = versionObj.revisionStr; self.revision = versionObj.revision; self.installed = true; @@ -1091,7 +1115,7 @@ var FlashDetect = new function(){ var versionObj = parseActiveXVersion(version); self.raw = versionObj.raw; self.major = versionObj.major; - self.minor = versionObj.minor; + self.minor = versionObj.minor; self.revision = versionObj.revision; self.revisionStr = versionObj.revisionStr; } @@ -1100,4 +1124,4 @@ var FlashDetect = new function(){ } }(); }; -FlashDetect.JS_RELEASE = "1.0.4"; \ No newline at end of file +FlashDetect.JS_RELEASE = "1.0.4"; diff --git a/examples/audio_element/js/player.js b/examples/audio_element/js/player.js index de9db96..10ac84a 100644 --- a/examples/audio_element/js/player.js +++ b/examples/audio_element/js/player.js @@ -25,7 +25,7 @@ }).on(); dancer - .load( audio ) + .load( {audio: audio} ) .waveform( waveform, { strokeStyle: '#666', strokeWidth: 2 }); Dancer.isSupported() || loaded(); diff --git a/examples/fft-microphone/css/League_Gothic-webfont.eot b/examples/fft-microphone/css/League_Gothic-webfont.eot new file mode 100755 index 0000000000000000000000000000000000000000..08deeb7bbcd5472cfe374cb72faa277dca33c381 GIT binary patch literal 45426 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 UJKEM-pPb_sKD`=P?K9{657;%4 + + + +This is a custom SVG webfont generated by Font Squirrel. +Copyright : Generated in 2009 by FontLab Studio Copyright info pending + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/fft-microphone/css/League_Gothic-webfont.ttf b/examples/fft-microphone/css/League_Gothic-webfont.ttf new file mode 100755 index 0000000000000000000000000000000000000000..efbe8b461d7d50b4ac35f8862057b80ddc1eee46 GIT binary patch literal 45212 zcmeFadwg5fl|Op+(a~F$j$W2!S(aqkRvcMYELm0*#}Ay~7!!i)rm0EOG=vZ!C4>+t zO*3hRVHlcpQrgl7rA*5(3}yPuFy}~yrYVE~r8H2Q=`bX}3{7cDAH%P7N;{pjA+d75 zYo8-qjuR5@%pdpO&kb18dFW{Gwbx#It?znlfeC`(!HXnBhlZA4@xj*}UlIh?j1IG{G`nA_xz2#=X zAeaTgjNcR-*WI{v{om)_eh$a7Abj0-{k2!G`{Vu2e-wmAnsL4RdYq`a!Q{m8DjYXo zzwy?OuUePC1IK?Z2!>DIxapd!ul=+BdO`RmF0*GhUj6Z#*(Ce6ApEcI;zabOt2bUd zXZd3E=YRbi*MENVrY*PbJo6u)6@-8MKHBs7n{T=H<`2L4ovnhP(DMiAA@~zsC@Zhi z`}e-F^;`6QaQ^W#{0dqk)X^D1#4!_I#~<}X#2JpT!v_nD|*Hd_fS!ZuVKhC`iWpjal3p(cTR|64p}_ zrvLr9AS4C^VWe{A=B>AELI0wsMC0+v<7~5eGrymH17l@8j<+cPMFT$3UjsiPJ~8l5 z4T8ilMtH^meqRtiDg2%A_rgC2|0GNZdxgWo3E>RuWP|Me>}vLL_DS&t@mSOr^+oHW zjnSrPYcw7GNOVuEsmb$G;grZ}5)~fA6CM@*5l{G*@U-y1g+Jj5m#{Im22a>7eoy@0 zQ6VZv>!J;_p1{tWIrGMuXU{xy=IJv}p4ofmi8IQXe>(HnneAt8I`fe;??2OfrZD;Y z$)El7z)!#P)4f0a)=wvXs{ZsJe)@@@cD(-WpS&17W;~|#4*mFV{9_mwPCz_^5ji?R z`T2zfJqvsL`UfrlU?8?#ijlF;Q2UdJ={Hm27TJ_=8A6av?aO-Wi zZ@uHMKK#oJFj z?^XQV_N$`*sxWUyT}ol?(SK7M$&@0tUp_W|Y5b~KN-?zGP#0AOM#p2yz*Q+lYNxNp z;;~PR9}B&FRS5TuPlkSTRVW@)jLC6j=wny$3s+r*=Na2;R;^4argpW7eG0!G{nV;e zAw|Gr%uHAKYls?Q4 z#bQ^5cJZSz?TCKRrnOEE$uazhy*>IbygQEeXj(BRSB*!bOX5RUZ-|aZ*R9naLHE_r zFXN}9yP`{W4P71I72Or*KNnYov2kSpccOpvv&z7=bb#+T`7iYzu8YM&(Zjny27Ku< zwCw|W+t5DT=4y{e59>c3kB(pd{!mO|SB>vNhc1inibr={wkv)$wS>AuuhbryhQWhj za8n29gXgRcprP@h_|+TMRQH6w>TO3ScHK>68(A0MWmcl2;|oIvaK+bN5(e17;2^tv zuPj_6@K?I|188}4*VuS`Em|KR4B?H%2SNFPvGF40)uL+#i!93UrbMq%g4Z_img0&2 zb_Hia7rdl21{WbwN$wahOCc3m0WyzPqRWJ$#DwI8Q4%_&WD)0*OtGXD>98VXRI~9- zg=I>jS+XQ23`W5vB^5(@Lgb%RD@zKhV03#Fu`sXGn>EA@xvYQWxA{AgM~uf$Jzn1M z#vAx4pTRSnk9>jM; zLWEr|6zkE}qQ5qn&1Q=hw6$oqJMeizVD*-oWJz>4gqs6dRgm5+`2uyJ=0FBLh8l1g{|zW(d}I4t;+Hl@Bpv2-Z)vKo|5Di&EaODCr<)^;e4 z4y9IB{kZ6mRXg75<&s!$_9jaP{%WFEB`BAyK?^?A$|YN^9UuI1smAZXZ8Cp#^H(3e z(merw5585$zlCRpD$i-CJSR-|lo~5{M(Dg@piVSYB&_VNmaZM=`KJuj6Pfc_ZybMF zLkxdebDaOhy)i@Fn~!;8ouTiwe7FAj!t(_t6`o)4Oz1$%{`#kTo?lo#g_qZv)KWgp zo_LOl&$5ThtLX39a{0OP2z!G5a315{a;8nZ$Fxewvu=SY^V5p^u-XWY5~7FQD#M3H zSPL8=X8@?9Nbnzbf6#GEIO`Bm#RcQCWb>}wPwtTs>^VT}xbqF*%o^c<-(7JVl8H=63iACkYpK<1R0X04zpDWWQ%6JPsI7Ti6!X; z=9=Wh678tL!;c#H5mT0?72)tiy~Y@rj}exfaA-%Ed2?{orycdl>S7#eETmqcvCBg5 zo4?`n8B?~7PuZa9q*5oV0nc5Ffr8@jV2IVeIk=E4 zD2v_21?eS)LV-ra-PLEvWr!Fk`ds$(sV1?p$8K zo)_JXgQ=lWNy3ML)bOZujo5bQ2W_U82pW?EUtp)UETTCUe?toWiyRp znE4E~f$n_3WUdYPF#x7$Yrc_XGx^qpQ}p_9skOU9#7Ou%$Hz9<3TF`w)i9A9CQ!^!+QCQ24pG?+-Ro-HqIJATyTSlowu7q3|p zi$7F;`>{=Hw!~ijTz}24FCX~yvtJlozT(pl*jhejXxeo518c-ksx7j#h1R;1;SWs0 zdSwzigrb3X9Sg6O);crsvm$0xqw!7tX901H#C(i6E5zcM+=kTf@R7}UhV6|v$|vx= z!SWH&V#)~t78ew6S}~=WQkPcPVYLR-ufh5Re)nY5pvLy!{p!EBX;LyEE42qyr}?BJ zA5dB$UQFhWgMw-{bsVJiF8BLmpVMwM$%^rSVwM%FcAwWn_j$b9eJ>vP@tXEMRSK?uxG`1xbY!d zeC6VNZt2oc{X>q#x@GJH#AfoRd(-LV&Ybd8`FQ!4uMLeMJ(b(7X7yo{XMofdONC#9u zM#p<#-*-Rz?~Aq5R#`D0P+fe`Bt?)*Oc05`uexhX-?A-!>`0um>*6drOyuspC5`1>X?g*e6x|1 zLscg2(%``Su#*tT2NGFxK41=*6XryIB>AxSe(%G{JzMTvw)D;|(i>kGQk0=DH0>I_ z@4nGp7`qXcHoPX?BiMy;SYog-vJ*@a7CflBEH`W=$5EKp&aGiW%xiD>j;; z6IM-tNtvS6MwhK-+-bAYN1I?xsx_LXnv1!!?wCL3j=M+LEqmCO^6ow2&OK~p`H?;4 zN7za(56UO-yKg`qvorzYi&kVa4avYgo{9^^XxVxcI~+KzP)`aDS)~2(wh(0<7!La{Q9s)qaX;i6Ew17buC)Z`l68*1Q5>%tp{`u(Yjzu zE0)7#X%#JI;xG$wm>qpEL)TP{T7GsaL zG$~fMB4Yw(bNN2elkaK@W1*6xZkfgW`9yHX+U4TCKM|LK-&eoZmw4k<=Dcq2-WzUU zca?XRl}Y6_v@eBm+=}*H0u-bepizvWO|byADHg`mGEqDGaIVip=lU+OCMV{l1E!j! zI**2VFs+D(RUw?osF$FnjTz+S_gVsOcE)aTk<%ZpBql`aFt*YaXQRH5&Y~i`8lh zUk6NF(l)wtUEL%S!9(#}pRrejmJXf6oRT7iO{2?h$;V6^#2uzse#^4an-|7SN5x1o z6%<92+2e@k>Is4A1EK&Ag(KaFSzK=Yp>`Z-+4{{ zmo{9x(z7N!WRKN4WpS@)_XL|#;l5-leQ9j%*Jz%A&qT73ZGsGGSF{qR(UhF9*{xzt zQjxN%O?p!?LBhJziuJJK$fy=j%aFl3L6owXFbGx)eY6tyc}VoyZJ-D%D54w6Fa&T8 z44C!D!GwvdI~O+x*`j0DUH9Vs_t!Ys@Uw;^r`w(_@5Lu}B*ifY$Y6~7r_rt!;V*?^ zl*S##chMN7-!bBMiZV6Q%XxL8&K{L9-gUUcUPpJ>UBs=eX~o64)rSTIO&tQ?1W*dCNS7O7n<80|kaK}b$6LXogW@H}0;xnpPj>X9DW}}^$)|Q?{(By&9BKgAogMoV{8&u2}L8u7~G~Y zpNWsFuJ_X7M2k9BIgYm2|L`YT9VErjVN{GAia}OQwv&ocRwdg>gMibl2{%K(?-D01|g@@I|hAXJ}}i{nE0#(T;w2%cS~VP3C@^r|4*Dr{jRT z=<+p?L8x}NV|DQv3VeceX=aK65(8F>xfU-@1K5h2Cw(l}1?qc!wIn-ejB;DnOVRFI z9@vtLN!M+WVujluzP%8Wj);+TOWYFL5OURx1%quZ^=wdia^w2Pb_8-8M*I3kH{=34 z9$UZhNhO%yGUZV@|ntXsEZ^XhTFeilHRZPUESDZ^)An9o3l z8CXk1N`OfAShyBMvRCt>B4_vvgS-{_BvaxUH3X^=FN(yA{(@rR#0hznT96|~bIr<$ zk=0qw6bJud%JqrbJd1J)BPNHbf` znUIBAmTVbMvKBDmvSnLWw4Hvm{D9#yPiLEteaDyX^kCi*rWu3RjWEsJOwGn9Ldr;7 z%i+)_RCvrMC^j^^NWUQ*Q&+j5bHi9L zV_Bl7S+%D*K%7~M90x|B%q>}hXOlXoJs&bsc+7AV;Hyd40E|qt5n*8H^CbM`7Y4L> zLTZ$FK$Yw#p+xQb*$tKR0?wOo-e93?PMC6VL6EY~Cl6^@Y-0LI*XSY3{Z{55G2Amb zB<>S;KFD5sq5MGkffr~_qtEP^;i%-`w2YFbNxBND&Qh9iVtgVx>SUvt$wmf_OLtm>>(X-x^LHOeKQ@N-7yo_4^`1|Qeo2_gQ_U2OthfSPF2FSbM)(Rt)JA# zDLpcuvodsUMBFzyWVq+C7a+;jy-;p>koSw$$yLTTg@_O*>w}ar(kGeHoK`%Cm1u_R z6R`|b3N>g?sy6UOi>B)L83IrPd@kl>eyo69eJtOd?{1B^n#_i5E*^9wm)<%!c5|0+ zwBVVyzcbyIw3(U`=^>|djTeXECt+d_-PwVkJ~ zC#9ON9fmaKYYH0OKMKV*NV17$Noav4M;g*ZBd7g@dtMtfqX{?HA17*a{HRvfCV{fT z6o_#+2H2)IU7*7K#OGQZ;hVd71g?;IrKA`goYmR$fgBng-= zo59t1lYg*j*#obBby@sjpXBO^f9`Yfg59?A;L7p!w`K3!_{xR{mNl_g)194Z7;;;a z>o<*zY+9c@{j2$wK+7KXi*Gi$%yHFR z!(o3`b8_E-Z=JZ6UzR!)u|tt$)gWR1K~TaeU@RH!62ND(Tr!yn^taF}wC$3W&hI<$ z*+2djzHBeq_+kIe+9BOvLw6SOIt_;uao6;bfG;^}i09dWQ=jU(iqrB>(xb>su@@iJrvR?PCcKcTlq_ zyD|+|a4|{xLL>Br#w4wZjd84s+`#nXoS$1{{uyE*H)-gk3kWhdBzi^YrKBf_i7M;!hoWS6 z#_Qt=7@~=ITk?lf=IBft^w6O|G!}r#31gI-pob1k8KpE2D&y&f)Ef|rZW>M9I^?4n z(X}*qLSab*(*nZB?Lb(E)Js8)c+fGMl~f!WphlzYG{*B79B-~GCns7Ht?{wPR_<8a zm++WOoz+`MjSLTBEoHoY zOTlk;;e-0BZPoAyMiNh3wI_^-0)fQC+EY(!4{#dDI0!KyDFmom(P}9(0o=$2{6jx) z$mlSQ2GNk^67!F-cgkr(5tZ5E>n`A{WCB=tn8t_nD8MPVRugNIQGKqaaKT0gEc7P)Z15wPJAAKPh zyKr%MR4?>a*bl0OTfGe}xTTfrYt<~OgCWGA92|)Q>53<~{H|irW7D|EILqBxKeT?? z=5#Id#H%rqU;Ro$L{96-2$R1v=@}khw0ez3iwb|*g+Yz>KdfibL`k2c#%IZ-t40yw0Pd$&+o79zE5)bNL8`(`fwo7JkPqyeSmz#2SK4_jhxY z&BK|1FdHyG7I?C#7X0v+PidN>42#MFt;qE?gLTS! zK(*Q|ii{OWhMRQXGvD~#Zd#GxQYblU;ApNq(N6a`>7J5{UW<60UW_2ai@1IIgzzn+ z$;yL$Dhm-Cuo+F25TMFQU13u#WH3mYXmR_qc`Q;`tP*iZ$FXA;``#lj{qlc*#bm0< z8jqLl!65suvir1CyeAUbHu=^Rt(JpUM&PR)&%`qPCTAc9UkS-HsOCijpQi>R1_b^R zK0|4ajvZqy7~Z#Dp5jHrZamA6C>_4;se%=B=iF!px>?JgNA|d1R&AJJkOFEzqyK^8 ziLVfu6&Y0aKp}T>MZN!hC;ov>Lot_0Pj|XbVhr}_ciSOsOKuOmB}Kee6Or`y8aSaV z^kM^6?G$3DD(A?1$yA#k;#oA4G0Jd}<5uXKHvnQ1G7Y2#i+>{ScaJgWop#A~Cv*Ow z#|8K{SwY7T!V_?B3jOx;gFWNwi z0NGENt)#$CnWNgE5U^*>P~-|3qNIM22vV(P@P@IViUg186E0ILo8mzd@i4~6jy>}F z>yNA-7+hyO{z^Ia>f|Gao)6t|=Xy@Z-Qtt5OF}|YSgU#W)hNPf+|gPKz(UM7t}xA^ z1*)BMMgtnrph2{R$fwYf2Cg5~WA%xhYxQsoOl~2JAI@?*qN|0&A z0;+B%T^(c6#{p#ssIA*}AKTIsN%lk{J;?~f;IeXg`D8-eHhGs}*p^s(-`WKEhFXC2 z+>bHpVs@dJrZt1)pqJDMD7Q?>r4{+G8bzz8qHm(wylu#+DVz>v)NXC+zW9wF|GhSK zo#Yf&n*q$tJ)pp`Yjaw$3^@2}4ZT9?D77@t#mQFwn&7W<_-h-z7IAfYhLi0GBa(;H z6!92}rKzDn8eza;wK;esXpOVEh3HfH2mj>xE^+y1j1o}ihXo4>*l2Kj01L>WhLjdM zke6Y3LY>hAXb?$|$z}ooM$KJuQ^40~h)9jhFSh`tYdL!TO6E@2bkDI2Ue@h_pb0?xxl&R&mOz{)Bh^QTkhCC z;yWsS!IO+Jv52+_{&yh`*8p};b zegVz!^z#D)hMtOk2z<%#2lUx5{6Q%CY0Y$MeJ(MR0|AGc3gJII;nV!f@LT|Em~ir= zDMjM*fBZA*CU=}d&oH=88qqCPaDxOJ|H$J95QON&d{k|84Z%<~xOQOupMG{03I66! z|HaSPu-w`RRhUTvoSR7kn_VLTfeICjp+W-H2R#D|hvIT0h6GaFNkA{Wxukwr-5dbd zNmL;eln$sK!5@qpWz*^hSDW0@_{%TtSzlvuTnD}U^zS=64NmP9`uRZwE9b#CGWh04 zprM<6SYPq%4tE8$0U!^B3}p1AD|+w3-@J7_CzsHnSUU)#aU(F$3brtw-1nSUzX*WF z4wwei#6`$#2QKR0wBtJnvw&u+3KrmvI1oXreb32nZRXT7$R)`@3UT!pO!S44nO=bw zmTYbaL)C4yfLTj6ez*SHc6wqBf8x~l@dX!sp(N955zm?)2N-NcoF>WWDira<)0c{P z4CzPTVv@;ht8vLRHuMhxh8zc~#DOBvUb`^;s;xGJ*{en;Uv0dG3P*E=+iZ~k@b^}V_d&c7__mdn$7Kr#5#>h?{F47J8#8#P! zhDHmbuxnO1#(_d*bPJ8^h5q02Fir(BPqAZpWVAerSRO@iAA<@nqSaioTS**A#AEcq zK$=0N$q;_dqnk{UY17f;n1{k`H|BOp+Z(n=C>>^OHetX?BV#(fVwqC;*a%b`8_O z8Zcqfj(}u9TH`kYFj?a8!N$heJukjk-Ygq`_uY41d7kU*mNQEYvgrZXwSBq%)fj=pDG}>N3+bPz=QnAr_+a=O1 zpk(N6$NE)iK4ddR_cGYS@&qh1>Jq|L^iDu|2b|!K6<&IYeYSkFY)pOk9Tz&mgq)#G z3gUN6!bb(o>Jq_F=5)nrFu(curF^byF(sXNd{DCm z)lXAaE~v(kE>s9G;vI7PfN-^@nLo#UwD3^Ek3M#2eCe|Hja?BN3)Ur4u~;eranrqW z*ZU@OV>?r|fsqs8L?SHS8crlB+=u)Bmt*Wg!gAgF??z+Y^)yy)KeRamHQ9l44ju^L zun@M~z*|rDG>mB@E*Mnfcp(R?1$z{L!F{ILui%NT^#c$3);ZwdmB0U(>=(jc?! zyyH+^yucR3>ki$qv-~I4!~PFj`k9IGyR(UvlMk; z71~;fw$fR&)v;l+DlGx95dp+RTZ$7>B^ReHMeEfRREcP7fxw2Fmq?3vE1LC0-h35p zM>Mh?;v_y4O(hbk=u6^DplhI(z4%UKWaZB78g+xo1dplG;w#2M-#PHcBI1Bgi&{{# zHck|-4H0@z4Nt?T-R6o@czGLlp)sY46Pad1TLz$(S`RwU1%Yt_7(Nma)OySW)f`7x zbSsp{P(bX$liw&(=m-Vi^T2PQ_1-Mp6JUOmiw#N*T{n#^y)hdW%ily8u|M7-9+1MF zH!U66)Y%~J|B~1ek0nHr1;nf)v3}XW!WGLK!{vSdSz}3r>+<37C+=`0)-LPqU9lp< zCcfrK^cTVnBtvK|V=uvH8KT%Op8aAYxl2ri91EnC@MIT-l3Bn+^*q2hh#q+}#UN+8 zU;rek4-$3i$%Ftu39wl)K!|g)RbqRx6kn|cw)??YfiQTAObp)*QZTh`%S;Sq|(aFjQRkd#6f?2iu$e=8K>a6xuURvkn1 zQ6Qsa(i3^jksM1;EYcmx<7vgt9r7PUt6MUfd78uL56bEg#su*Or3IlO01auJtj(xb z;bac5p=uW4f*krFEWTL0tHk z6hOcRgjt@Xk70G3wm!Yl?TUyf4p@k~E_r4nFVPtzE!QkeLA{ z2s5|iq3xrc*&d^Wk>5Cc_mcIChv(U(Nax1OLXL24UpQ45Uzz>k7ao4};N3mfv<+=o z+8GH)qGWK`LcVZh@9L%TTT*L6@vW&O>vXiNUD|iudiL$Qq4IOK#78b$CPM#Fq`#m0t$`5WY?_)F&*_Bq&Tl zO?L8W;v(6Jh(H*I6kr8h9YzUFahlx}4hZd=oCpXUC*X*bFp`(~K7_#4`oSPr6u|%P zu|v_u%VJBf{9(ouvsfS^W6{RWUGF=+!Ek$L$l*M_o6B?Xatv*u7>#+lJm*e$Xh58s z-!(h~KTA;*V}}kMlGdDh(C9gI2pMg!ly|TY?_V87S;BlkXbQ;#nkBSOP{amPf;^+m z4^0Za3}6kUSs)T#3fu`HECM=a#-QdFGLF*o+>SK!;s;aVhJiyg3l@h{7R%N{Pgp)< za2cd+r|!&NvSlc55+&2!Xo^nj?OdjAug2~9N=4KryM-uCj?!u5{+XY@{TZ&+OyTop zj?Yga@n-?-MZoK%^iS}tTCU=2+C7ilJP($B$mY0q-xr^JVZCHC*8}!l+1$)p%3qjt zu;*oYu)Lki8t{rfJ{Rd5IW+AX!FLS`=6)QR(Hai#t|#mq-R1&WsmT%$rC!m(>usPWQ4R4v~mOK^ST%j=?gLh5{@T6W)h&SScwV*I} z#fj|C5PJstAhD}?w2E29-leg132E6#bm{1`^F0Zh{n@-{j?E^mS>2o2E{&wCS$CR+ zEAt8coH?H=y;LuLKC!C#Q9Si{HAmLTFqhJ~V!mT%y)Qwt!^xdUyx zK-(@Yp0G{x%2VV=mu9=b8Thy_YHm%WAwR3vy#NIdBE<>OThQ+G<ls zpQ+!_(78!l`owT{9A3 ztHT|u!}2%zGEfsu4=nEx*P)-JtH4VEfDH0 zMe3bT3oP$29=~i_4J_xx+et|wMG&eA#f|L{S53EhTD77!S5zw)%at}?jCMsF1MSK> zOS{TJyK=u5?dmc_eZ0iAt7K4bvc}u&ZM4~m6`apuZTgzfta=%KCn+2iiml*U z^6D$VEWOJb~+@}=}?d~W%w8Dhq=x+g=2@OGDb;=AY&Bn27(%1iT}%o zG}Bj0tBLqdDoqEbQkIm6T#81T0K>%SwTREtSc?)XP!0{jEsvXH7HcG`VJU3J5r-*^ zVFI8%@TWr!Et{!H0Ebd)Y*S&t& zWL%b;-|2p4Q9ny3Q~TK+cMosuZLzVTZ{9ufXM=+~m*&^5nlIKjtRL^WQ@kTKno2(L z;I_S;ORgEkGyz?GXWnKLz68}28iv5w;pSPiiVlVa%0=KZ|=IcSK7cJIDqX=-rsM^Zrv+9C6of4y(= zmA#gioQ2_!4;4gMb4*x#;Ui`kEd>p_G7pkz+#SKa+@izRHU-;)LOc*~`jR{X-zv_vvaaDjq&MFAF zpCjOYKj7ah^~=aXcOnxVM5=|VKtOOU0N@+`bO2wj#=yVwCvrvEmG=k$BgsiefSpyj zVw#e1LA=-Z)FoDjZN;_~wi?SNPd&0{)Ml}d?g3f8H83DvroEnePz?0TDe#FF?O_ zz*?m;2dN`@Po*slqoNa zf)$wl&ZQ+It;4|;jS85HiJQpPW)UDCd~r;&N@Fj6Pkvy_Dmm6W47M396h!6J(jEJy zy?}cc(foy0AWD4xQaeeEke`by0#N;F5?3L+6eBi`?DqWe&4;L^)5vb{wSw%=6I=vgl>iU(!qL%7allq_eXc^_~_jy4!8%|^M7|u8{7T*m!v(& zUMX+6XW7_am$%$LD(;cK^g7$^>mDE)kHMkn;dpX@?xyKxH1`dF!DjSjV>u)(N@)@IIi6B!U<>8F@&pD9rw8f^H~ ziD%@&&f%VCPLzLz{4H-``1BC(2tuAkbm6(J37?-HEDJ89@o9 z;dFenP>Gz74oHUf5uq}3=b3n5^Pup?CyR7-f~__*+tb*%P44k#;GiZ>+yD!SNa zNnUvA*1`PEU4;#c3s-x*cT4V`p_>P`etFA|bzYBg*wMCOY_KKVGR#(`QUyo*hS9~> zj(mtGR&m{u6~O;wN5iVG%5UIG@Qms$hD!AorWH$IGpn~qG#wdOD8#Z}o}`e!Bmc&c z@(yX~sR?o|6E6&&xl3GXitq?hs+mH(KsGGG$a>^pY3C_WN&wlPdWWEeUMB+Bi5vcKX7qLg-BFs0hm4FR=RnlG%Aq<-Bg#N&Qt72 zXTkV_n#$rfp&PeZ+(jup4=2?Ihz`{mAwERrCO6ySxoiT67abu40-0h^n*2TlfcxXM zW}g{09_lJ^J&L0`k|naSza{eIy{2W6!H(?`V?kDs=ePMrEKfQ< zy)OIhmRP~z==UwU)wXGT@rIrL^7zmvHZ2y##kb!*wqmm=u3fzOcyQ;sk?XfuVjgK< z?GrDo2SNqjqMQthHxCNWY0=5kzQhTy&n;lo99hZ{M6N6%t|w}P{G25_p=CVqyzzP} zEkn=(fxGq$)>axx8Ts7^j4isk`QQc)3RIMU--6PP%sO+*#hkmharTi{z+?T1i3iZ5=1;);(dm0*{n*f|E#@*TFK9$fPez zU`_I~Y9S&FQ;HI{nf&zHr;Wky;~zbn=gXP$m@8&j)4jqEgrXVqh0?yLMhmZ3A@k1@ z3sPoEPF%n#Ura3^il#CMM-H~~3qkEdD_^}@V`NVBQC$j3o_Ara;Q9r8Gm+GCPm;1a z57dtFN+&6J2eUH=+j06v(Q64U$|mP5DENKbx4Z4}sM|UDoBoI_Z{Lor(rj`q z%32{miv4%<`6bGKoEpzYp-nh-{t<16@`2Op>l7P!8g2s|CaR}ClbP_f@vA-^m79Bx zv24`FGE&J-ov77L)Xo^lq&}S zb=8BfHWQ`?c%}xCfl~wC0MNf^vWV$8MnWTBf zP+u)BzF>SFGmh74pbR=_J^CB>86)_BvSQ&J*9$CA79A_F&luwmJ;a}JKjgq`75}kT z??De#r;=$^{^NYs%&L|8}ak>+dPaOMb~C2b8g6rBjV1V z|D4+XO<-3m&U_Ajc<4O18)Ylt^5(?~kf3Pd1>2A>MUB84dFNr4OBgXK182%W6Myg8x8;x(PiW5cU@M6v(cG091q56MfOM`n&dUfLlsCv_Y3>`XET z&m^mvkx4ckqtsuWNhWIx3}upGDSG!zG8fMzb4_KEAyB;JFyocVp4HI#=}a;wKdjCq zbJLwgyiV&GMcg%gB$TKoC(XaAOfs!dC!L)B$L&mbezZ(7JH;y?60SO%>?21$`k*u; zqs$!n_Nj02q_Y2?julGIq@w{f_>et1gN}s_NB;KnGw5hq|Lti)R`a7%@G;kU_|e7r zQLf@gBsRkHM->PNXCp|BRG%4~>7C|G?}a$i!#UG4#hEDYRC1Z|N*N6@ouB4RH$SZA zOds7@#OpLK!nU2knQoMdC9+jY)csX)0GTi{jB~ zibpR*@d&4QWQyWZP`ts6SHiKwbbgxRjr_2h;xW3jh}SBL5A-M))x4TjsMQMOWv-*sYOZ-s#FNh};^(hZ|>($C~>R zEuw6(-j_(o)>Dsj5hCewIIYWJKWjM8$jp|+RL#`GIUnjjPvSwj9SYwEG)N9c!2oJXhob#{r&LMAx`q%rz`2dru7F8YEwYG>EJ<>T-E8l8T57myACr% zEkd(^iEvg9wajONyLu+L(i1QaU{4V4qgfUl^|BtG2xzu}oIyb}a`d9w#zc*#{{!Wj zH9vgQ^8;ZC@4i-g`TX!s%@1GIgiyS4$wQa+RnG~(8TTN?*Ec;2inwd~NWho0YH7e= z2@0lq-aU!AcgbQ+80g5M&Z5Z$=A0s^rxA(n`%?Dt=ON1=WzjXBA;I+cF46(6eh* zO6|tN(fjxR@q;OwSzkC@Ayl)&FyRgAiPJ@Ef=sVa_Pqc%1O|1(J0-UTWX(W`ct~sm zTtzK4IF@)dHKeM$<1%|#+@vMzmQ8Q0{F?`D#!Akvmar}&n;SV^&{e5MSX$^7Hob>z z?mSn533|+CW+!ydhg_h9?vg1vuM?w)obJbw)1Aq6)4_X9>-PGy=4?J!l{$O=?C$Rk zv|XRN_!RH*4k*~WK?jQSSqeSX4sNJKJ?m^hfI)=^&dQ|bDPxt4X*hJX!Pm#Savt%= zl;dOtJyZwc{1mfWtw9hu;JoQXXP7Qna;NgE%kd){P?AbdvW6~5V^!ToR2Cq4QeoBq z!8XFXz*|Tywd=6sjCMlnnr`QVWHwdWNxIgIc6x-rxX5-=XpbvfhGJ;h2de%cG2ja z<~-pQ?zq^VAc9}!J%Ko23IxOXlkE}Ut#~Uj#xjyJFrNf@nsI>LQI;r4jkCE03lafT z(>?J#y>@?9HxA+-;=A5~LD~<#Caim|R;!$c@pJS`;&t;V5&@_eoIqeu25<;JWdJi8 zU>lkcRlVRC`0wQXl~^UthwQ%TXYzH87;t9z8Gk0ZomC@c*U~s30*#pG*wK#?)4UVW z_~p!gv~dE@qZ&aAHT;FUfhYmlkk!JzQ7cGG4(HKzHbfR6QAslK^@0(ONChzPbgs7I zhXz0M+U_R@dOMHNZwwFX%{QER3BUDCbDGn`E?ing5n%sNIqBEnH|Kd68hJ_vs@`6y z*$cD~#YpG`Mfd@KBVv)7K%K*TZh!Bw-u9)$EK30mv#2UZi@uFUCwMFa$5`^&Q7m3%}~+_C*id^LB9ac623yuKjhJ9 zU=PY%xIk`j$>gPa{X9K5sHF#c$jb-*oGzbINk#Nxo_H$>ia_)T)~#Azr)s5SG5t-` zWh!Q_t5xMYO*P+s=g?UtJpTv!R79T$twhE%?^4O^si!`kyHA7$TtuIaV8#0CMfAzI z{M)lT#j%*_v1&w>YGict%BpdS9Hg;Il4CQigtFKI0i%}Y+zkgAIlx-=sR}S(jc^6Y zTNk8JYjvv)R7I-BGu25oNGNU?a_t-gs7tzw=x=g2mxPXs?DFvNtdX3_pGl!d*sAv# z)kU>F&qtrVRA>hk+GRDXQ=u2{?V!R0@$MWVLzePq zG$J&$&`7IusKg3(5@;kII43F2F&8g}w^z@arJF8>M9Zqp>vvv0i|N51l0KKy`dm&6 ze|3)8OxeWkoI{ipMEpEX9xd%(!L}=IttfAr!uP8x0VwTs34#2)WD+k>gHiwuZq^X>EKOqzwunMX|B%7sb#9F~gmyDx!nm3)iI$#_64;-5c zuaVi5{7q6fn@}hOs*)OM;5e|W;bi5a9-QQY_2d-rO8AaDLeOs`y-EmL#M{2!zTe!4 zN7+kr_*p!w)JC^YJ*G654iWF?nzm@MhXqw^!GkEl6nXe=N+)%?8>85RsbbNhU<)_Z z+>MbrQzx~AM+mL}(j{^UJzWAK3+eNfd@tC1`s6{+>3D9en zo2r`?uTE=cecX28x%Kb;_fWOjJp1?Ffc|*C-@6MY2=tNZ-)qDkIJ{Z_^{-kmR{~EO zVJH+GwEdgz zJYk?gmw$HbxR#;p2c!@Ei6)$NpcMoP$`Sqtzotp1`B3=*QY72bkox)#NXW2q}zgw1VyY3;+@Fj09dhI6urO=bP zdX{Zk&$1;wVJ^l&jUzf-k=?Y5P{dP0u5E&N2dOM!)MZ1uZ95h|q}$HJSqQERr`wVk zGh8s`HV3ihxR|tC;|+UH+bXHI)wD^SO`D6%K-OsUt{KQg8$AP=DAQ4)45gufGR5$` zP7Z_o-%dp)@7e{@ksTz5FESmn@mhS4S}C3c@AW^OD!<)>3#EzB}y}YP9Q4>&d*z zyo{2?tW#RE6PS-&L&qiopyq;VYA(>J*{@TRHUn4yYL?=yZG_~WmHJ*n%^sp1D7jFh z<^v!Jw7Dcp;r=Q&mS3lVqqEYH~Li=*?G;V^SsEaWh=oE9tdSkmeUV13bK zTn?3-t0+!VE&+2-fxg-b#Ug`*4@ma&loqH6z3wTYH&<5LNbb=jZ%wPD=ejaV8`WO{ zKc{tBSTsQv>eNS4ubL-`*a~`5-GMd`*=X}~9jP3LCX~Ci}zx$&njAy8Tl^6o2PMaDm_uqKJ{`w=Gl*k znFH6N6ur`oss)vWq(h!aXs)tEn(8*gIi_NdF&-;j>Zy-llPv_+Av-;4DH1}z7Y2oB9tqYR=-?^*nbc@c!hL<#Nm$p~gL&zCh0PW-o?5J9t58F%W%BsDf zJ$)vTT1?C*uT`QQG2}ilGYoi&cu+3GMm|37&w>gvu_!v<2R|4R(7D`L#z&wBBOnv` z3C8P@RqR|wX#=!Bz@m)OB&&0AVsVC#R5+tvi2>=M^x^phbpUyJsu88^lqR=YOF_7E zJxUkIotTdsx(jNw7dHq!xPT<|O9-W-L{=Y_!P5z!n^9W>S?DMhjQq=~x&x@bq1PRt zT6j~{Hd>}D5X>Be<%wa1MG7ud`6AA#Peh+p`2zc2aFnyy z5JnU;5v*uvPQEuBsbE3#z&S zDs<&I72Ilfej4??03D_ZaFDWh0Xj?-;V_Zb_g)HdutQM&p!?C@E*ejyA&1~kJ1Wp-V}FqPH_iP3pjVEZ73nG@kfg5#9@z`gcujp zxlr?a)p4Sk)OP#TO#Do0ydB}^8PlvK@SYK|%MNt8pTs|3-`C#9m+9Ot^- zMUjn^ifNjWUU32Ds(m_8A=%db7sFgq?EBxJA{jdbB||*(I*jiakM}hrl3n*kRziKr z!^t!KBqN_5+{1}Di5RAL`p_Yij(X=;h_BUsS?u1K&yfyOH8BbqrstT*Q;I#HN!;`R zAIo9(psogh3Te%^iPuHVr-^5fPZLqVGd-Db2qSVCnRVQm$$g||3$f-bPbM0udotV5 zMuaCXS)w;n(0!TEPsz7yr%Wc=iJIp(U{eO3uZ)B^%5M5^cr){da{DR&fqoT5L-2_( z4pCT&xxCu=Ct$fbs@6!Ab*6R=(rPq8sViCLIV=daMV3AkU+dwL%L>n>N{TE}-%$_S zha;U0Q9gyVTcEsrJ4h6e#CDKYOUFT`qEa6|%Pwte$hodV&k}Hp61^p}1yC+!q}!|< z@1<8d@22zEaj+V?1#XMm3AY7kTQb|6TIBB3Cmx8D!@5#5*kiO_wz;1$I_je>NrDv= zp9hvBs%1b0Mt?kxtqLqPTCs7XmB%4H_M-byuZ3RO?ZE3=Lw4j7E<&3i3 zXVvC7r}K11{hQCglDn<3I>vE!1rKAe+H3<)8nk*Im~%m7l4gZvdPNWJmm|xpgBB01 zh*cIcFDvu?&S;Yjs$G>OjRKuYxS#Na!sd8e2aUSZqc&h2sa7kXS5}6ZU?lk*Lw&BA z9#O~{$)cC_pbxyL$BbpPs-y>Wh*RZr4Dwn1OrxJ8dOsu3-+4_UzDR2Qgr`VJYjvb6 z{fuMvd%|aqw9M5avz+c?YldgRRY~@$KAww}Nn1EqAHm3Hbx@q8D^zvz99%4kBtB=1 zWfYNV>-0Xt(AN6c2~Gw)9?ojj>$GUJZuGXBTN-@p6beG?#;9_azA_i%+K4(W?K~dM z>48=ZTMw)oielg+)#^Z1@6l7j{KbnLWPSNJ&7#B1C9R4E5?}l;G}cGJ(iK`_ z#5pI6q{{@#k0hCp7jCVR3L#RSa#^(=MC{U)CoUv3om&$UJX%F7s07d047s6nk(Pvg zGx<(XT?iQ|`OI-HHxeAH&U@f6JfG}V3T@e)|r& zW1UJ!R%{2<`Y@^kAHYG$8p8Gjhzl(_>QVaFh(tB20Ic6{r#l+x4me}!ZR$cPR{7o> z`hrwS(_0buR{3CKKmZCw+(2tNN+Ar`sgf5m;i9oQ>53B;@9@LY1tcB=s`I!!kQ0uXJq@wF!76G+ACV2Ql96+2#<{a#c!qkZVL@j(rj%NyI$qQvVq z6*_#Q5gZ-Z?rA}}CRs-C{&dME@95T+TM`L!1G1*i)sadbHTK-4S}EXj z52`KQLiQ2uZObbvfwA>sUer8l8LB5y@JD~*zy5}#jl|2h+p!r8%A~kZi`njQx@dm0 zB2ozO&SyB4RV^|j%qr?i5hW+-6Q+WnByxx$t2N=L`JAuvItTX;_jV4|ZuzSFds-pYN6S?~o?6f-2m~N|FUJzB`0D75b z7p$#jURzyb_pIV-T))!jf1K05UbqjdB5@C9fEU~oz!vWW|C+K>h}08lV_fZRhUUMQ$j{mRN39v74Ry zuh~Dl;EfRu2yV3UTAunIr&IMAxp9mXT}_%+RcE1K=XaHXCp zLi>VK!awbKNVy+~qNZwBs4!sRxgQpk0mIhNb~x=V@&q#qwSci0-yRWWB%%yd0eywi zjRgf2L6KKa$s28#{ABA^)-pLMb{^{zzh16cee5HXPrWRzLmN=8gFS&Z*r^6OuN$xZ zzE(1RD*d2n<=bab88Vo_1l!xNRjnSYJpF5NcVyk6b?Xk{hn9(VmBY)9Ej#_XxB~;f z7zzT_rw<6N!u9%|ciNUYeE++tjn*b?JONqTbgc=Ho!#liPHU92R8N(9;ClgGr#D;U zz5yH0Si(kg>KsgOJz8Z-N2;~&%g6^!JB2DOS+xtiUzaI%wGq*}XlHfO zgDCH_A6G8VOkC=1ql(Cv>dN(%yn~A|>WgKS%nh=fFXc60iT#IAdj}`vj5>;I^A{t~ zvCZ7Ipr6AD?xHmTmj8bcP z-jUlnr^_!F3RHmk9A+K+BH`he$7n8z+Fm<|73vh`Gt{wdC+rA?@U?O?s79{LPphzS zlpJE9u-i2D-66gE9Q6t*cm(wd7igm9?0t7)*moy!o_%*>atXd0!~~+OG+vweYYTsE zrPm^^R;iqbKW#?d62f$`UE8dEcjC=0t%({Zc0jNCr|r9Q&P#lKqRqzC%zQ{YDu7rr zgt8pJpR42dyb>Z(zT~z4lc)cw z-hn4~zjm&zdBl--*_y}r{O~Z3x#M*yv8K;~MPbnJ>Z!_7=6qPcmIsZ_~jeD>nEB#{XwJnxny zm6ctd+M48!{iwb(V|x5icHQOdUn?Aok|djh%JR_i%*8QimJ+X z`kp1oVJ7Wz;d|M$q-d}qfe&MD$1H{oicq^8)Auhylqk)+s%=ar-+8jH|Eb+Su54#w zj?jb=c^y6{<_op|Hm&_LD)G&1In@TjR!0`BoO+Xc&QXj{+bWH3vr-gI*k?u4hMmX; zDjAFxEy1?B)p~6{z17nt`pSNd<0_^4j6c%Y3iVAS)Kz&0?KZ);OIcG|j+U0E#dlz@ zcsF=u6JD{9va|HuJ0@vCP?|RbDoxe%(%cfD6f7i7(wl@q(;g{l4ioK>l<-BxQuJ0c z>8V~Ka8(;4#(;R-_$s1N=L+Cql0&=z3y({ku<)&JDJ>JKn1fU?*a_4^G6+y^`Fhdz6q5rcJ9fMShp68dK-e zEvdK^yYGj*0y|ikt(VH;eTa>rT=6jh{nfL+;W(jo^Eel@dq!=js>)B4Tv`KtvScus zMXVKq>Vm8)fvf_K=5-2s+)1k*Z^G7p=#y7n^~oA7NqUq=jO@|kL>OBIdj^{kz%IZZ zXxyI!DZ&d8a`N#imQR_|*4PC~W}TuRKbtp`;lfre zjz_PtMY{UNQgS}CX7elA8|uTB@XBOci+7g?(X&+d$Ah{*N05c(YE>o@~l>nj)NmZuWwg`eXxp_@Kb`ETk6)K?PRQ-grJPD$3#27RTgTKkI z*2Oto(((e08dI9UlqiY-FCKh?R8f`t1j%|4B?tvtqbXrIYd!+&@gDpUt8*~of1+m9 z|AU?(?nDN_QqZZ1s6-Q169U*iNw3aC)WNDvG(mNy5%FGe=X1|toP`l_r{PZi-N3Bx zR(-)x;9p=ur{NC_`yxQ*q^K?`SQ1Whcu;lmfIW-efepbte3^)nFGwt4-M zC5At|!EEIdye4A`&y)D`Is|UU&3qnNa}=>ofAmNr9tob}$Uz*_*N_?>KC&6lu)Xm{ z`2_ltDxW}os5dm3h=NZzsI<;_SP@XQA5Wq`dYXX}_fd_LmJK{B?oA!pyndLT#B5j> za)v*MJ-lr-!V0aoaOjc`*<2|`fOVSNov^Rab4W|YB-7Tsln08*Li^%zGEj_o4U%Os zD^M>0VpC;Y(s?zqWVN>(QD?lGL^`2nwq>f<+f#;o2Zfl-?T)aa&ah6Vz($z0YcreGTD;2tPO6;de~fLce;DaJ*m z^kUi@;s2`Z+JmAxulV`y-CZ6ouq?}4V3+42i0s13L*6W_uz;3Oi`FK}$Wx1mXjAKC zs7WTp8Y@i3WE>}B?8~&4E?etltizZY+9nfQX+kw=d`6o@Ypj2mw6!DjckaEbVD&PG z^L^jF-{YL`+;8vqIOja*AFZ2Q=li=>e8&IOzS4S(<+(+2NgiD`=H__>XJkBXq5m}$ zaJi1*f)iB~n2>8n^m%}68QIi1I@;MgDmywyN4k1PM==t^<{R?PC}mN0X39he=njauG-^Cv1R9*I#n9f)HQVX6i*UQjkVndyY%c_j_zLt!q1 z)2xt`swKXPbK{Z$%a3;OKRFE~*ekefdnP*0=JZ$CIaUE%zW5IC*;NyW7Uwu`%$S|y z)gZ-Q0r7!fDp)#<^oJ#4It3jCEuGaT7eA{w@sy;r;o;%ito-D0 zKfON9*4i3twZ%fs>b8=eQC^gk(AxS?IqEie3mdeuOK!tE9t4eWXiu=(3cPfpN5M5V z{UURJDpHI$%O4zJ#wlRM_zuj+sTLm}@8VQ@=h#Iij<+5URV@s{`U}1i`16rXONN^? zqcOg)C2YD!aa=lXj#7WSFix}QBIx75K07-`fcxvn22tI;RT%cv8r;L(%>}FU-|gr3u*ud3|8J50gC>O`y59`yTyu7?g&OvFkUKflIeu zvC&JBwn!TvK4DPq@pr#pe+TPf+sK~`x%9;s_#e1+GBPW1(m~TFsB*6Vm#A;#%XPGUwUvz);f0`H-~1C*jnm4KGIpG2C*o zuLkz%#*V^OcTbYh=2}-_tBl}TAi|2-`K zOmY0A_^8t8>Cotbz7W&HPG2km0^*-Q02Zv0l9_-ccHT9g7XCEEsV{|=NYJ7wg3h6U zJ2+FJfz8LT!>WfA{N!v#IY>~QRy`!(UW(qKQ)tjUSE>CasCufm(fdq9*_V_O%pFMY z7GIqW;Ms{8G86^DkuUrp!t{)Cp`U}c&L9}nKRYoyVPFrY^RLTdnVKNIiE0oQ&%^F# zJ(cLD$RQo44EY8X$*ajBT(nqnPz@kk`YAQ&((xS9#3|rva!FGZEKQSJd`z$kNk!5a zoD1nEVJm%H)YeX>Y5Fy2p+Tlx?1AfOv?mE3YD zwTSNneol}=q^+YC`7*$cFzQAdTBMJFuK`a`hV&BYq%UZdbcW12BieG6OsGFx8bBQh z$QOq;C4kl@a_LT@EhI9)2M5~Tg7(w^5SH)bSwCQe zDwTZ5BmRZ>4$2T;BA=g{rL|;|hY{{Y{X5YP3(E3Qx!8#3V3S)Bi#1c2{AbP z9(Zhdz(3~Ud|0ONk9in?(htV*tNWfL{Z2BD@X&UcwG3 z)^dXS@dcn^luhVw66Gq;7r?vlj&uXFtZN`=;y30D;x6^wP~MMz$aer(&h=qvOC`V;yK`WZv2q1ABQ@Oe;i z(C5L0!DAtrA)O(2LwiFHg#KZHX+hzFT?@__2g1U`hQhuI_k{l-{B(pT;<<=J5mTm4 z(_VO@8jPGa$C>w{MK9+*rI6|8)Gh zgxrL$63Y@h6OS!4E?l(m^@Z1y+LHXq#^kExTPdX}Ln$Y$9-Gm&-gY$AoSK_@AoWV> zm9)6D?sQN3RQgQDWX7kN{>+{=3QEnuw+mEqWo7Jx#+x^!lOtqxJ7M7#i#ieGOv`cf83@_^a}^dtdM#@t*X4(iqy9 z-?*dkbW>d8P7(+sk1NCE@TYdddy?tZUrlop_tJavFiy_ z3RtC##JW%vMulidPb~U39`cchvj|D>?~sCeZCD9NqjYF_W#U|s9cyBX;H4@TbM`z~ zm}9OuaSE#tGn%D1i&cysFNHOcGU$UFuI7up<2&4MEG{7Tuh0`V4Q%Rr;7N&_%qPAJJu@6MA6~K_Xa$h)}_{(8ENyh!7?b zi8hgPn`5!%_)wSAytMf^7#V(JoZu`I%j?`)G z@YJa70Cp0+C1zjriI>Ui3trVWF2uey;~qm!o6Tohs~ literal 0 HcmV?d00001 diff --git a/examples/fft-microphone/css/League_Gothic-webfont.woff b/examples/fft-microphone/css/League_Gothic-webfont.woff new file mode 100755 index 0000000000000000000000000000000000000000..2e2cda96faeff036607bfe11f1db97352d1d61fb GIT binary patch literal 23940 zcmY&ks3-sk@MBtm0ObFCP3Hf^|2_ZzCMv2Z4FCWo{;)XzL1h~@Sxi_&^oOhYiSd3w z00ajB6_b-y_~B;$i~oaVoMVibf|B45ck>f-{6KgWeIr9wfsPRX0H*$lf9eJ3CW#3N z8CdDr{&1c@+WsHU$aB9MV&LpZ004mU|7f`X1I#x3ow2Qn)erZduJ%V~gwQ}&Vxs5p zlM7D&qk;Xu00BUlSh^Yia6fr+C;&hXY7xs#zp0U)ApoE(_oMk~AHe#Y4qs*ZL;i4q zKQaCfNZ`!C;Z3a^U4OX3pZb5k42ZX;A)BA2jlqvjwdJSXrXTbfdGcXd>AC*2tNw%k zd0(JUpjK-=E2AGS_J@1<(H&4I3dh*mI5+|T8lgXN`%j(mVc%D=w)RFpd0N6hI{yEl zHP-I-szf9<#{=owPS?W1j10VsQ|K)yv|5pM4|1V!Z)?h|YcS3@C)L=(f7bu+m<9iwq zuQxIJM;0`kf!~#%19B2*z)}~TxE~b&$_j4yzq$I12AMrQV?BMG5sRsQe)4#NOge_* z2KxNqaImmv@UXDj^xgtS@(ckW0ev=POCdh^jOca0{1=)0A(KIuLii>9{Ez@bbZ{#F zTc573v9B&BxG2GBPbtU&ga0daBryLP5Tu%)BW}Nba1ksO<`R>o-b$}+)Gl_vkEoC+ z`H=3A@DTJ6XYu|Y7qk{sVbns@1Jp#+1=I($J+vi?-;_{1x-XLt-+VKmV8LMgD9ZGe zVCgkkdVKwG!T9_rIG6z#D86J1jJO7Ec|ExVxdeFx0eZmu-{0T(-+T|>JKvw*&mY^j zKI`9b-^<@R&)rWxTi-9=z28>f8eg9e&$9s_2+n*fx4Q2EGzhG`s;{|cep{be&oY!7 zMx8LXxJJHlQ9#zP#3-@4f+_%5NpxjaXLuP}YdmdUZy*6eJtTPsJ17ZCGfXuOH!u-W zBQzxzCpc*uD_kueFAyPO0~7@&2N)?T3v3N84+t@GlV2)qE(o%8HuySx-@ZM$JFzo0 zH=!e?C#fqfFM-0r@pE@$LrqsupD5(A>5NuG4{7yB6WLrgz4<{ADYR;}o`=7|gA)~X zFCL7HHl`#@C@dg2sNk-8%Es>!@+QtDzy_GopXZc< z^UM3r!q?i~(vQ%Ci>Ioiow%NiuGc!rZN9g%0D(8Tn1C;zpHZj_whQP7OapuYO@IbK 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 Yumm7QumdYZ0k8!iMX&=aL|L#DE2N4B(f|Me literal 0 HcmV?d00001 diff --git a/examples/fft-microphone/css/dancer.css b/examples/fft-microphone/css/dancer.css new file mode 100644 index 0000000..9219137 --- /dev/null +++ b/examples/fft-microphone/css/dancer.css @@ -0,0 +1,113 @@ +@font-face { + font-family: 'League Gothic'; + src: url('League_Gothic-webfont.eot'); + src: url('League_Gothic-webfont.eot?') format('embedded-opentype'), + url('League_Gothic-webfont.woff') format('woff'), + url('League_Gothic-webfont.ttf') format('opentype'); + font-weight: bold; + font-style: normal; +} +body { + background-color: #000; + margin: 0; + padding: 0; + font-family: Arial; +} +#info { + width: 100%; + position: absolute; + top: 0; + height: 52px; + background-color: #111; + color: #ccc; + font-family: 'League Gothic', arial, sans-serif; +} +#info h1 { + margin: 0 0 0 20px; + float: left; + font-size: 40px; + color: #ff0077; +} +#info h2 { + margin: 14px 0 0 5px; + float: left; + font-size: 25px; +} + +#info h3 { + margin: 19px 0 0 15px; + float: left; + font-size: 20px; +} + +#info ul { + float:right; + display-icon-type:none; +} + +#info li { + display:block; + float:left; + margin-right: 15px; +} + +#info li a { + color: #ff0077; + margin-left: 5px; +} + +#loading { + font-size: 60px; + color: #fff; + width: 500px; + margin-left: auto; + margin-right: auto; + margin-top: 100px; + background-color: #111; + padding: 10px; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + opacity: 0.9; + border: 1px solid #ccc; + text-align: center; +} + +#loading a { + color: #fff; + text-shadow: 0 0 10px #fff; + text-decoration: none; +} + +#loading p{ + color: #fff; + font-size: 18px; +} + +#fft { + display: block; + margin: 0 auto; +} + +#stats { + margin: 0 0 0 10px; + float: left; +} + +#songinfo { + position: absolute; + bottom: 0; + left: 0; + background-color: #111; +} + +#songinfo span, #songinfo h3 { + color: #ccc; + font-size: 12px; + margin: 5px 30px 5px 30px; + padding: 0; +} + +#songinfo a { + color: #ff0077; +} diff --git a/examples/fft-microphone/images/particle_blue.png b/examples/fft-microphone/images/particle_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..e99476c97d4f61cb54161c15a138b742afe9219d GIT binary patch literal 640 zcmV-`0)PF9P)Px#32;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RX1q1^*GhMhmCIA2e5=lfsR5;76 zlxuGiQ4ofo!!GPaD8+JFsEI}swegGb|Nji5t&M4$trjSEkcF}^ei+!g;bPMCBD&eS^KdZo6z1QS@D$E zBXAkRWU}^G9~KLc9Ze*nv3_5*lZoc0Y!k;2MaX>{+AU}`F{Kh%HsUz2siTNmr`JVV zO{Cq@oSnZsi=f+u%L~NwA(z9fR!}TKE~lD@2N?E|>nr5jSGc^;oLRKP*l`Sl9ukI_ zoU0RKID{a;tUE;}V`w&!tDkWG9SK7i^!9YhrdPWiWEo?kDRSS&1a-vsH9nncAK!*Z zcmsn$;=jaNJI9ynLg5ICMK~%ZogwoXjD~vi@n{RSANcPaw6p2)6)z6XMf02!`>?T} axc&lD(CVB5MPx#32;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RX1q1^)4D!VwS^xk7RY^oaR5;76 zmD^6+KomvSjA!Cp2+gH|5P>2U#54W>U+4!QRS1a)2u)2ONgZG2(uYX{DG;g(OY>lP zw0zE)wQT`-KIjrcc<~-k%FTP{wnNpM4>Uwt5Z45e76E1h{vzWtEO=s`~ELOnIL5Zq_0;~zp7eJ+<(UR;96<^L`PQJ$U zk2TGXL|2|#-u)cWXoVM81IvZOl%8VgH-V8Bw0aTyL(So-rhlwy??>oZAXX=>V$gAf zlu%}##nkcm!}9CVt$}hqyPBZcjp!XIIs+9div=Tlm+LlBbU8*sKx&i>aeKQ0%n-06mjYh~DVD;QrQ-&fUhWUwpnI z1#w-{>_|EX!Lv$rm6QTzi6yx<%o9sGcbMX(0I!~9r6#CU#Y)-$^e%K!7M^V3U$x-f p4{W4ZOY2?G%lqw$e%LPn;5WThGLz>n&xZg2002ovPDHLkV1lQFHPiqA literal 0 HcmV?d00001 diff --git a/examples/fft-microphone/images/particle_orange.png b/examples/fft-microphone/images/particle_orange.png new file mode 100644 index 0000000000000000000000000000000000000000..0804be8ab0bcc9ebd26dd50e684eb51e6e053337 GIT binary patch literal 694 zcmV;n0!jUeP)Px#32;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RX1q1^*4h7I~Hvj+vNJ&INR5;76 zlwD5~K@^6cnc3~O+ft-0L~I3POyq(XFZus}z{JRf@dH7?Qd#=R_G3G9yqH2Mv^6oF ztKFP4&zza_&Z_|7KZR0C)Zc)ifiUpj*%UIn9vZBI#E~M7pj1$VW(Kq{7z*ha(y=Us z2g_i!vSR0%rcu@GRy2j2&kZN=>&9`OI9eUYb?+%Ocno{KrP)wJ8ES&y8>Z2 zQFL$Toz8&)>})FDy$U!w2zdY6u(z!#<`qW!8tWA0SW$@7>>mchY~eodfpMhRt!NrG z&Hj$2UiC*c8kF(?qXiQy>Qzm9Ae^@R30hqt9ec6pyW+=aFO`hX2+3^ zc{=5EEVMep@tLKVS41H=fl5gcg`POhgqwlz<Px#32;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RX1p^l*F9I7~;s5{w4oO5oR5;76 z)LTyzQ541T-%O|N&_bz25RqU^jN#e%{l9~6Mjm{yMg%O-%XDbx;sfK@ax*dRlX*Mm zKj-YV_6kt?PZb0~8T<_x2}DAWDP({7fAkn67KueVnj%33EG3pwnN;>5JbDP$7aNG} z>)O*5Yk*Yl%*?5ok<^v+9yGcOd#+<&*E<7mY&*22rwzt#3{8A-?X!_c=t8mvjaFfs zTAthR&cFxzj_o+KrK<^MmWC#FY}7qXWu_K2bOjh1h#lMU!M^uicyo@VlOU@Wq$U)6vopR-&|(T0*(fPjg?5?dljwr4=w-Rkbg6V9Sx7 zZEa1B3U|92LQM_Z+K%)b*wPn^MYR*cRZ$uOO`(QRB&=_?T4CkOTX?8(XHWQ;K?|kw z0iTsh#S`YPftkY8!nwqm#N1MT2U;rSN^?tR66cai;bPr3nNliqVeZt-(6|<4Q>%Vf zt~9mq&D7A?shJD&wW+C9PGv??CoXj~wMBA;7rHj8ZF89)WHENequWagz!IjiEQztHc^3%}d-uSJJUMe>-mn$Te&Lv*z>Qs}GSo&_}tFfVp zYd5w3>Ii!%zT&EPJuN-$`o=eMV>iYYrWW^Lj{;Y7@b~v84~r*rG5DW}{iLz~wSEEP W(cZs6MkWpb0000Px#32;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RX1q1^-38{jI761SO9!W$&R5;76 zl}&5vKoo|bd<;pnM5MJyHz(lq@UD1_kp`Wnyk==FL8K|l}$s_ZC=`1tr> zG#c^x`brcxV}wr#WD?~ziL zPO5;FN`+RdrC|MjAK&+>R;w6>L7wMaU0u;=G_WiSfX!w@mSspO)t#1rK@f0zd&}M3 z9qo1-*L5)rL+x%^7N%*E=Q(j4Gn>r_!;sZ#rGWZZxfd4~c%H}2%?+OCsgr4%rc&2+ zY}=+@ujBhZK@f0xd0CQ{{;y0N$H8@7Y};0_6XM0PEL_)BcXmls` literal 0 HcmV?d00001 diff --git a/examples/fft-microphone/images/particle_yellow.png b/examples/fft-microphone/images/particle_yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..86d67f19488230fa4ce2b613d39eb84311282b73 GIT binary patch literal 627 zcmV-(0*w8MP)Px#32;bRa{vGf5&!@T5&_cPe*6Fc00(qQO+^RX1q1^+DE#oI2><{B1xZ9fR5;76 zm0fGwFcgL#S+-#pG0Texf-$*5q0E?y_>+FAR5c z!|cKE_-rXF*Ms(esfsu{P<*~fxtiu&USt6{*aFu9cyn7JyD}JFs`f2VE5R_2nVf2_ zra51~HvSK9P`4m_#WzMwz5RK7cm|soE?X{jfV-D4mT{fJC=e>M~sI%=SB&siaNb| z2~{GXcdx)ZMv=T6GEcxjJCuJht|fm7`ocjBRPX$NOIb zd+%wz$Jmx~?Iko3R@}`EPs_TOumc+FS(Od52h&OWQn`1<{&rn5doV#6 z>wn)V8{6{uY&&V^h5fMgHn#1Lu-D`3e}}`n^YCBC*WL%L*yk?*;0K+MLOVgH? + + + + + + +
+

dancer.js

+

JavaScript Audio Library

+

Microphone input / FFT

+ +
+
Loading . . .
+ +
+ Now playing... +

Zircon - Devil's Spirit

+
+ + + + + + + + + + + + + + + diff --git a/examples/fft-microphone/js/player.js b/examples/fft-microphone/js/player.js new file mode 100644 index 0000000..069313a --- /dev/null +++ b/examples/fft-microphone/js/player.js @@ -0,0 +1,84 @@ +(function() { + var + fft = document.getElementById( 'fft' ), + ctx = fft.getContext( '2d' ), + dancer, kick; + + /* + * Dancer.js magic + */ + Dancer.setOptions({ + flashSWF : '../../lib/soundmanager2.swf', + flashJS : '../../lib/soundmanager2.js' + }); + + dancer = new Dancer(); + kick = dancer.createKick({ + onKick: function () { + ctx.fillStyle = '#ff0077'; + }, + offKick: function () { + ctx.fillStyle = '#666'; + } + }).on(); + + dancer + .fft( fft, { fillStyle: '#666' }) + .load({microphone: true}); + + Dancer.isSupported() || loaded(); + !dancer.isLoaded() ? dancer.bind( 'loaded', loaded ) : loaded(); + + /* + * Loading + */ + + function loaded () { + var + loading = document.getElementById( 'loading' ), + supported = Dancer.isSupported(), + p; + + if ( !supported ) { + p = document.createElement('P'); + p.appendChild( document.createTextNode( 'Your browser does not currently support either Web Audio API or Audio Data API. The audio may play, but the visualizers will not move to the music; check out the latest Chrome or Firefox browsers!' ) ); + loading.appendChild( p ); + } else { + loading.parentNode.removeChild(loading); + } + + } + + // For debugging + window.dancer = dancer; + +})(); + +window.onload = function () { + return; + + function startUserMedia(stream) { + input = audio_context.createMediaStreamSource(stream); + input.connect(audio_context.destination); + + startDancer(input); + } + + try { + // webkit shim + window.AudioContext = window.AudioContext || window.webkitAudioContext; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; + window.URL = window.URL || window.webkitURL; + + audio_context = new AudioContext; + __log('Audio context set up.'); + __log('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!')); + } catch (e) { + alert('No web audio support in this browser!'); + } + + navigator.getUserMedia({audio: true}, startUserMedia, function(e) { + __log('No live audio input: ' + e); + }); + +}; diff --git a/src/adapterWebkit.js b/src/adapterWebkit.js index 2981988..92ee7d5 100644 --- a/src/adapterWebkit.js +++ b/src/adapterWebkit.js @@ -6,9 +6,7 @@ var adapter = function ( dancer ) { this.dancer = dancer; this.audio = new Audio(); - this.context = window.AudioContext ? - new window.AudioContext() : - new window.webkitAudioContext(); + this.context = new window.AudioContext(); }; adapter.prototype = { @@ -37,17 +35,28 @@ connectContext.call( _this ); } - this.audio.addEventListener( 'progress', function ( e ) { - if ( e.currentTarget.duration ) { - _this.progress = e.currentTarget.seekable.end( 0 ) / e.currentTarget.duration; - } - }); + + if (!this.isStreaming()) { + this.audio.addEventListener( 'progress', function ( e ) { + if ( e.currentTarget.duration ) { + _this.progress = e.currentTarget.seekable.end( 0 ) / e.currentTarget.duration; + } + }); + } else { + this.play(); + } return this.audio; }, + isStreaming: function() { + return !(this.audio instanceof Audio || this.audio instanceof HTMLElement); + }, + play : function () { - this.audio.play(); + if (!this.isStreaming()) { + this.audio.play(); + } this.isPlaying = true; }, @@ -107,7 +116,12 @@ }; function connectContext () { - this.source = this.context.createMediaElementSource( this.audio ); + if (this.isStreaming()) { + this.source = this.audio ; + } else { + this.source = this.context.createMediaElementSource( this.audio ); + } + this.source.connect( this.proc ); this.source.connect( this.gain ); this.gain.connect( this.context.destination ); diff --git a/src/dancer.js b/src/dancer.js index f10f42e..8cec75a 100644 --- a/src/dancer.js +++ b/src/dancer.js @@ -16,24 +16,36 @@ var path; // Loading an Audio element - if ( source instanceof HTMLElement ) { - this.source = source; + if (source.audio) { + this.source = source.audio; if ( Dancer.isSupported() === 'flash' ) { - this.source = { src: Dancer._getMP3SrcFromAudio( source ) }; + this.source = { src: Dancer._getMP3SrcFromAudio( source.audio ) }; } + this.loadAudioAdapter(this.source); + // Loading an object with src, [codecs] - } else { - this.source = window.Audio ? new Audio() : {}; - this.source.src = Dancer._makeSupportedPath( source.src, source.codecs ); + } else if (source.src) { + this.source = window.Audio ? new Audio() : {}; + this.source.src = Dancer._makeSupportedPath( source.src, source.codecs ); + this.loadAudioAdapter(this.source); + + // Request user audio + } else if (source.microphone) { + navigator.getUserMedia({audio: true}, this._userMediaCallback, function(e) { + console.log("Unsupported.") + }); + this.source = source; } - this.audio = this.audioAdapter.load( this.source ); return this; }, - /* Controls */ + loadAudioAdapter: function(source) { + this.audio = this.audioAdapter.load( source ); + }, + /* Controls */ play : function () { this.audioAdapter.play(); return this; diff --git a/src/support.js b/src/support.js index 6f5aa3a..eff2e74 100644 --- a/src/support.js +++ b/src/support.js @@ -1,4 +1,7 @@ (function ( Dancer ) { + // Avoid browser-specific prefixes. + window.AudioContext = window.AudioContext || window.webkitAudioContext; + navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; var CODECS = { 'mp3' : 'audio/mpeg;', @@ -9,7 +12,6 @@ audioEl = document.createElement( 'audio' ); Dancer.options = {}; - Dancer.setOptions = function ( o ) { for ( var option in o ) { if ( o.hasOwnProperty( option ) ) { @@ -59,6 +61,7 @@ }; Dancer._getAdapter = function ( instance ) { + Dancer.instance = instance; switch ( Dancer.isSupported() ) { case 'webaudio': return new Dancer.adapters.webkit( instance ); @@ -80,6 +83,13 @@ return null; }; + Dancer.prototype._userMediaCallback = function(stream) { + var context = Dancer.instance.audioAdapter.context; + input = context.createMediaStreamSource(stream); + input.connect(context.destination); + Dancer.instance.loadAudioAdapter(input); + } + // Browser detection is lame, but Safari 6 has Web Audio API, // but does not support processing audio from a Media Element Source // https://gist.github.com/3265344 From 9f539762e283ef1ffda1506a541f144577b45908 Mon Sep 17 00:00:00 2001 From: Endel Dreyer Date: Sun, 9 Dec 2012 20:08:18 -0200 Subject: [PATCH 2/3] Remove deprecated/testing code. --- examples/fft-microphone/js/player.js | 29 ---------------------------- 1 file changed, 29 deletions(-) diff --git a/examples/fft-microphone/js/player.js b/examples/fft-microphone/js/player.js index 069313a..7290352 100644 --- a/examples/fft-microphone/js/player.js +++ b/examples/fft-microphone/js/player.js @@ -53,32 +53,3 @@ window.dancer = dancer; })(); - -window.onload = function () { - return; - - function startUserMedia(stream) { - input = audio_context.createMediaStreamSource(stream); - input.connect(audio_context.destination); - - startDancer(input); - } - - try { - // webkit shim - window.AudioContext = window.AudioContext || window.webkitAudioContext; - navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia; - window.URL = window.URL || window.webkitURL; - - audio_context = new AudioContext; - __log('Audio context set up.'); - __log('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!')); - } catch (e) { - alert('No web audio support in this browser!'); - } - - navigator.getUserMedia({audio: true}, startUserMedia, function(e) { - __log('No live audio input: ' + e); - }); - -}; From 18035b80fc1fd7b92952f423f3d6e620b853becc Mon Sep 17 00:00:00 2001 From: Endel Dreyer Date: Thu, 3 Jan 2013 20:18:13 -0200 Subject: [PATCH 3/3] Lint free. --- src/dancer.js | 2 +- src/support.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dancer.js b/src/dancer.js index 8cec75a..8012701 100644 --- a/src/dancer.js +++ b/src/dancer.js @@ -33,7 +33,7 @@ // Request user audio } else if (source.microphone) { navigator.getUserMedia({audio: true}, this._userMediaCallback, function(e) { - console.log("Unsupported.") + console.log("Unsupported."); }); this.source = source; } diff --git a/src/support.js b/src/support.js index eff2e74..74df2d4 100644 --- a/src/support.js +++ b/src/support.js @@ -88,7 +88,7 @@ input = context.createMediaStreamSource(stream); input.connect(context.destination); Dancer.instance.loadAudioAdapter(input); - } + }; // Browser detection is lame, but Safari 6 has Web Audio API, // but does not support processing audio from a Media Element Source