@@ -8,9 +8,15 @@ var owl = owl || {};
88
99if ( ! owl . context )
1010{
11- owl . context = new AudioContext ( ) ;
11+ owl . context = new AudioContext ( ) ;
1212}
1313
14+ // Cross-browser compatibility for getUserMedia
15+ navigator . getUserMedia = navigator . getUserMedia ||
16+ navigator . webkitGetUserMedia ||
17+ navigator . mozGetUserMedia ||
18+ navigator . msGetUserMedia ;
19+
1420var WEB_setup = Module . cwrap ( 'WEB_setup' , 'number' , [ 'number' , 'number' ] ) ;
1521var WEB_processBlock = Module . cwrap ( 'WEB_processBlock' , 'number' , [ 'number' , 'number' ] ) ;
1622var WEB_setParameter = Module . cwrap ( 'WEB_setParameter' , 'number' , [ 'number' , 'number' ] ) ;
@@ -20,142 +26,152 @@ var WEB_getMessage = Module.cwrap('WEB_getMessage', 'string', []);
2026var WEB_getStatus = Module . cwrap ( 'WEB_getStatus' , 'string' , [ ] ) ;
2127
2228owl . dsp = function ( ) {
23- var that = { } ;
24- that . model = {
25- playing : false
26- } ;
27- that . vectorsize = 2048 ;
28- console . log ( "setup[fs " + owl . context . sampleRate + "][bs " + that . vectorsize + "]" ) ;
29- WEB_setup ( owl . context . sampleRate , that . vectorsize ) ;
30- for ( i = 0 ; i < 5 ; i ++ )
31- console . log ( "parameter " + i + ": " + WEB_getParameterName ( i ) ) ;
32-
33- // Bind to C++ Member Functions
34- that . getNumInputs = function ( ) {
35- return 2 ; // DSP_getNumInputs(that.ptr);
36- } ;
37-
38- that . getNumOutputs = function ( ) {
39- return 2 ; //DSP_getNumOutputs(that.ptr);
40- } ;
41-
42- that . getMessage = function ( ) {
43- return WEB_getMessage ( ) ;
44- }
45-
46- that . getStatus = function ( ) {
47- return WEB_getStatus ( ) ;
48- }
49-
50- that . compute = function ( e ) {
51- var dspOutChans = HEAP32 . subarray ( that . outs >> 2 , ( that . outs + that . numOut * that . ptrsize ) >> 2 ) ;
52- var dspInChans = HEAP32 . subarray ( that . ins >> 2 , ( that . ins + that . ins * that . ptrsize ) >> 2 ) ;
53- var i , j ;
54- for ( i = 0 ; i < that . numIn ; i ++ )
55- {
56- var input = e . inputBuffer . getChannelData ( i ) ;
57- var dspInput = HEAPF32 . subarray ( dspInChans [ i ] >> 2 , ( dspInChans [ i ] + that . vectorsize * that . ptrsize ) >> 2 ) ;
58-
59- for ( j = 0 ; j < input . length ; j ++ ) {
60- dspInput [ j ] = input [ j ] ;
61- }
29+ var that = { } ;
30+ that . model = {
31+ inputNode : null ,
32+ fileNode : owl . context . createMediaElementSource ( document . getElementById ( 'file-input-audio' ) ) ,
33+ micNode : null
34+ } ;
35+ that . vectorsize = 2048 ;
36+ console . log ( "setup[fs " + owl . context . sampleRate + "][bs " + that . vectorsize + "]" ) ;
37+ WEB_setup ( owl . context . sampleRate , that . vectorsize ) ;
38+ for ( i = 0 ; i < 5 ; i ++ )
39+ console . log ( "parameter " + i + ": " + WEB_getParameterName ( i ) ) ;
40+
41+ // Bind to C++ Member Functions
42+ that . getNumInputs = function ( ) {
43+ return 2 ; // DSP_getNumInputs(that.ptr);
44+ } ;
45+
46+ that . getNumOutputs = function ( ) {
47+ return 2 ; //DSP_getNumOutputs(that.ptr);
48+ } ;
49+
50+ that . getMessage = function ( ) {
51+ return WEB_getMessage ( ) ;
6252 }
6353
64- WEB_processBlock ( that . ins , that . outs ) ;
65-
66- for ( i = 0 ; i < that . numOut ; i ++ ) {
67- var output = e . outputBuffer . getChannelData ( i ) ;
68- var dspOutput = HEAPF32 . subarray ( dspOutChans [ i ] >> 2 , ( dspOutChans [ i ] + that . vectorsize * that . ptrsize ) >> 2 ) ;
69- for ( j = 0 ; j < output . length ; j ++ ) {
70- output [ j ] = dspOutput [ j ] ;
71- }
72- }
73- return that ;
74- } ;
75-
76- // Connect to another node
77- that . connect = function ( node ) {
78- if ( node . scriptProcessor ) {
79- that . scriptProcessor . connect ( node . scriptProcessor ) ;
80- } else {
81- that . scriptProcessor . connect ( node ) ;
54+ that . getStatus = function ( ) {
55+ return WEB_getStatus ( ) ;
8256 }
83- return that ;
84- } ;
8557
86- // Bind to Web Audio
87- that . getParameterName = function ( pid ) {
88- return WEB_getParameterName ( pid ) ;
89- }
58+ that . compute = function ( e ) {
59+ var dspOutChans = HEAP32 . subarray ( that . outs >> 2 , ( that . outs + that . numOut * that . ptrsize ) >> 2 ) ;
60+ var dspInChans = HEAP32 . subarray ( that . ins >> 2 , ( that . ins + that . ins * that . ptrsize ) >> 2 ) ;
61+ var i , j ;
62+ for ( i = 0 ; i < that . numIn ; i ++ )
63+ {
64+ var input = e . inputBuffer . getChannelData ( i ) ;
65+ var dspInput = HEAPF32 . subarray ( dspInChans [ i ] >> 2 , ( dspInChans [ i ] + that . vectorsize * that . ptrsize ) >> 2 ) ;
66+
67+ for ( j = 0 ; j < input . length ; j ++ ) {
68+ dspInput [ j ] = input [ j ] ;
69+ }
70+ }
71+
72+ WEB_processBlock ( that . ins , that . outs ) ;
73+
74+ for ( i = 0 ; i < that . numOut ; i ++ ) {
75+ var output = e . outputBuffer . getChannelData ( i ) ;
76+ var dspOutput = HEAPF32 . subarray ( dspOutChans [ i ] >> 2 , ( dspOutChans [ i ] + that . vectorsize * that . ptrsize ) >> 2 ) ;
77+ for ( j = 0 ; j < output . length ; j ++ ) {
78+ output [ j ] = dspOutput [ j ] ;
79+ }
80+ }
81+ return that ;
82+ } ;
83+
84+ // Change the input into the OWL patch node
85+ that . connectInput = function ( node ) {
86+ that . clearInput ( ) ;
87+ node . connect ( that . scriptProcessor ) ;
88+ that . model . inputNode = node ;
89+ }
9090
91- that . getPatchName = function ( ) {
92- return WEB_getPatchName ( ) ;
93- }
91+ that . clearInput = function ( ) {
92+ if ( that . model . inputNode ) {
93+ that . model . inputNode . disconnect ( that . scriptProcessor ) ;
94+ }
95+ that . model . inputNode = null ;
96+ }
9497
95- that . play = function ( ) {
96- that . scriptProcessor . connect ( owl . context . destination ) ;
97- that . model . playing = true ;
98- return that ;
99- } ;
98+ that . useMicrophoneInput = function ( ) {
99+ if ( that . model . micNode ) {
100+ that . connectInput ( that . model . micNode ) ;
101+ } else {
102+ navigator . getUserMedia . call ( navigator , { audio : true } , function ( stream ) {
103+ that . model . micNode = owl . context . createMediaStreamSource ( stream ) ;
104+ that . connectInput ( that . model . micNode ) ;
105+ } , function ( err ) {
106+ console . error ( err ) ;
107+ } ) ;
108+ }
109+ }
100110
101- that . pause = function ( ) {
102- that . scriptProcessor . disconnect ( owl . context . destination ) ;
103- that . model . playing = false ;
104- return that ;
105- } ;
111+ that . useFileInput = function ( ) {
112+ that . connectInput ( that . model . fileNode ) ;
113+ }
106114
107- that . toggle = function ( ) {
108- if ( that . model . playing ) {
109- that . pause ( )
115+ that . onFileSelect = function ( files ) {
116+ var fileUrl = files [ 0 ] ? URL . createObjectURL ( files [ 0 ] ) : '' ;
117+ var audioElement = document . getElementById ( 'file-input-audio' ) ;
118+ audioElement . src = fileUrl ;
110119 }
111- else {
112- that . play ( ) ;
120+
121+ // Bind to Web Audio
122+ that . getParameterName = function ( pid ) {
123+ return WEB_getParameterName ( pid ) ;
113124 }
114- return that ;
115- }
116125
117- that . update = function ( key , val ) {
118- WEB_setParameter ( key , val ) ;
119- console . log ( "set parameter " + key + ": " + val ) ;
120- return that ;
121- } ;
122-
123- that . init = function ( ) {
124- var i ;
125- that . ptrsize = 4 ; // assuming pointer in emscripten are 32bits
126- // that.vectorsize = 2048;
127- that . samplesize = 4 ;
128-
129- // Get input / output counts
130- that . numIn = that . getNumInputs ( ) ;
131- that . numOut = that . getNumOutputs ( ) ;
132-
133- // Setup web audio context
134- that . scriptProcessor = owl . context . createScriptProcessor ( that . vectorsize , that . numIn , that . numOut ) ;
135- that . scriptProcessor . onaudioprocess = that . compute ;
136-
137- // TODO the below calls to malloc are not yet being freed, potential memory leak
138- // allocate memory for input / output arrays
139- that . ins = Module . _malloc ( that . ptrsize * that . numIn ) ;
140-
141- // assign to our array of pointer elements an array of 32bit floats, one for each channel. currently we assume pointers are 32bits
142- for ( i = 0 ; i < that . numIn ; i ++ ) {
143- // assign memory at that.ins[i] to a new ptr value. maybe there's an easier way, but this is clearer to me than any typedarray magic beyond the presumably TypedArray HEAP32
144- HEAP32 [ ( that . ins >> 2 ) + i ] = Module . _malloc ( that . vectorsize * that . samplesize ) ;
126+ that . getPatchName = function ( ) {
127+ return WEB_getPatchName ( ) ;
145128 }
146129
147- //ptrsize, change to eight or use Runtime.QUANTUM? or what?
148- that . outs = Module . _malloc ( that . ptrsize * that . numOut ) ;
130+ that . update = function ( key , val ) {
131+ WEB_setParameter ( key , val ) ;
132+ console . log ( "set parameter " + key + ": " + val ) ;
133+ return that ;
134+ } ;
149135
150- // assign to our array of pointer elements an array of 64bit floats, one for each channel. currently we assume pointers are 32bits
151- for ( i = 0 ; i < that . numOut ; i ++ ) {
152- // assign memory at that.ins[i] to a new ptr value. maybe there's an easier way, but this is clearer to me than any typedarray magic beyond the presumably TypedArray HEAP32
153- HEAP32 [ ( that . outs >> 2 ) + i ] = Module . _malloc ( that . vectorsize * that . samplesize ) ;
154- }
155- return that ;
156- } ;
136+ that . init = function ( ) {
137+ var i ;
138+ that . ptrsize = 4 ; // assuming pointer in emscripten are 32bits
139+ // that.vectorsize = 2048;
140+ that . samplesize = 4 ;
141+
142+ // Get input / output counts
143+ that . numIn = that . getNumInputs ( ) ;
144+ that . numOut = that . getNumOutputs ( ) ;
145+
146+ // Create OWL patch web audio node
147+ that . scriptProcessor = owl . context . createScriptProcessor ( that . vectorsize , that . numIn , that . numOut ) ;
148+ that . scriptProcessor . onaudioprocess = that . compute ;
157149
158- that . init ( ) ;
150+ // Connect output of OWL processor to audio out
151+ that . scriptProcessor . connect ( owl . context . destination ) ;
159152
160- return that ;
153+ // TODO the below calls to malloc are not yet being freed, potential memory leak
154+ // allocate memory for input / output arrays
155+ that . ins = Module . _malloc ( that . ptrsize * that . numIn ) ;
156+
157+ // assign to our array of pointer elements an array of 32bit floats, one for each channel. currently we assume pointers are 32bits
158+ for ( i = 0 ; i < that . numIn ; i ++ ) {
159+ // assign memory at that.ins[i] to a new ptr value. maybe there's an easier way, but this is clearer to me than any typedarray magic beyond the presumably TypedArray HEAP32
160+ HEAP32 [ ( that . ins >> 2 ) + i ] = Module . _malloc ( that . vectorsize * that . samplesize ) ;
161+ }
162+
163+ //ptrsize, change to eight or use Runtime.QUANTUM? or what?
164+ that . outs = Module . _malloc ( that . ptrsize * that . numOut ) ;
165+
166+ // assign to our array of pointer elements an array of 64bit floats, one for each channel. currently we assume pointers are 32bits
167+ for ( i = 0 ; i < that . numOut ; i ++ ) {
168+ // assign memory at that.ins[i] to a new ptr value. maybe there's an easier way, but this is clearer to me than any typedarray magic beyond the presumably TypedArray HEAP32
169+ HEAP32 [ ( that . outs >> 2 ) + i ] = Module . _malloc ( that . vectorsize * that . samplesize ) ;
170+ }
171+ return that ;
172+ } ;
173+
174+ that . init ( ) ;
175+
176+ return that ;
161177} ;
0 commit comments