Skip to content

Commit beb2e43

Browse files
committed
Wired up microphone input to web patch
1 parent fb9b8c1 commit beb2e43

2 files changed

Lines changed: 138 additions & 136 deletions

File tree

WebSource/patch.html

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,18 @@
66
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
77
<!-- <link href="css/custom.css" rel="stylesheet"> -->
88
</head>
9-
109
<body>
11-
1210
<div class="center">
1311
<h1>OWL Patch</h1>
12+
<h2>Input select</h2>
13+
<div>
14+
<input type="button" onclick="patch.clearInput(); return false;" value="No input"/>
15+
<input type="button" onclick="patch.useMicrophoneInput(); return false;" value="Microphone"/>
16+
</div>
17+
<h2>Diagnostics</h2>
1418
<div>
15-
<p><input type="button" onclick="patch.play(); return false;"/>Play</p>
16-
<p><input type="button" onclick="patch.pause(); return false;"/>Stop</p>
17-
<p><input type="button" onclick="getMessage(); return false;"/>Message</p>
18-
<p><input type="button" onclick="getStatus(); return false;"/>Status</p>
19+
<input type="button" onclick="getMessage(); return false;" value="Message"/>
20+
<input type="button" onclick="getStatus(); return false;" value="Status"/>
1921
</div>
2022
<div id="patchname"></div>
2123
<div id="p1"></div>
@@ -46,18 +48,18 @@ <h1>OWL Patch</h1>
4648
<!-- patch.play(); -->
4749
var getMessage = function(){
4850
var msg = patch.getMessage();
49-
if(msg)
50-
console.log("Program message: "+msg);
51-
document.getElementById("message").innerHTML = msg;
51+
if(msg)
52+
console.log("Program message: "+msg);
53+
document.getElementById("message").innerHTML = msg;
5254
};
5355
var getStatus = function(){
54-
document.getElementById("status").innerHTML = patch.getStatus();
56+
document.getElementById("status").innerHTML = patch.getStatus();
5557
};
5658
</script>
5759

5860
<div>
59-
<p id="message"></p>
60-
<p id="status"></p>
61+
<p id="message"></p>
62+
<p id="status"></p>
6163
</div>
6264
</body>
6365

WebSource/webaudio.js

Lines changed: 124 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,15 @@ var owl = owl || {};
88

99
if (!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+
1420
var WEB_setup = Module.cwrap('WEB_setup', 'number', ['number', 'number']);
1521
var WEB_processBlock = Module.cwrap('WEB_processBlock', 'number', ['number', 'number']);
1622
var WEB_setParameter = Module.cwrap('WEB_setParameter', 'number', ['number', 'number']);
@@ -20,142 +26,136 @@ var WEB_getMessage = Module.cwrap('WEB_getMessage', 'string', []);
2026
var WEB_getStatus = Module.cwrap('WEB_getStatus', 'string', []);
2127

2228
owl.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+
};
33+
that.vectorsize = 2048;
34+
console.log("setup[fs "+owl.context.sampleRate+"][bs "+that.vectorsize+"]");
35+
WEB_setup(owl.context.sampleRate, that.vectorsize);
36+
for (i = 0; i < 5; i++)
37+
console.log("parameter "+i+": "+WEB_getParameterName(i));
38+
39+
// Bind to C++ Member Functions
40+
that.getNumInputs = function () {
41+
return 2; // DSP_getNumInputs(that.ptr);
42+
};
43+
44+
that.getNumOutputs = function () {
45+
return 2; //DSP_getNumOutputs(that.ptr);
46+
};
47+
48+
that.getMessage = function() {
49+
return WEB_getMessage();
6250
}
6351

64-
WEB_processBlock(that.ins, that.outs);
52+
that.getStatus = function() {
53+
return WEB_getStatus();
54+
}
6555

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-
}
56+
that.compute = function (e) {
57+
var dspOutChans = HEAP32.subarray(that.outs >> 2, (that.outs + that.numOut * that.ptrsize) >> 2);
58+
var dspInChans = HEAP32.subarray(that.ins >> 2, (that.ins + that.ins * that.ptrsize) >> 2);
59+
var i, j;
60+
for (i = 0; i < that.numIn; i++)
61+
{
62+
var input = e.inputBuffer.getChannelData(i);
63+
var dspInput = HEAPF32.subarray(dspInChans[i] >> 2, (dspInChans[i] + that.vectorsize * that.ptrsize) >> 2);
64+
65+
for (j = 0; j < input.length; j++) {
66+
dspInput[j] = input[j];
67+
}
68+
}
69+
70+
WEB_processBlock(that.ins, that.outs);
71+
72+
for(i = 0; i < that.numOut; i++){
73+
var output = e.outputBuffer.getChannelData(i);
74+
var dspOutput = HEAPF32.subarray(dspOutChans[i] >> 2, (dspOutChans[i] + that.vectorsize * that.ptrsize) >> 2);
75+
for (j = 0; j < output.length; j++) {
76+
output[j] = dspOutput[j];
77+
}
78+
}
79+
return that;
80+
};
81+
82+
// Change the input into the OWL patch node
83+
that.connectInput = function (node) {
84+
that.clearInput();
85+
node.connect(that.scriptProcessor);
86+
that.model.inputNode = node;
7287
}
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);
88+
89+
that.clearInput = function () {
90+
if (that.model.inputNode) {
91+
that.model.inputNode.disconnect(that.scriptProcessor);
92+
}
93+
that.model.inputNode = null;
8294
}
83-
return that;
84-
};
8595

86-
// Bind to Web Audio
87-
that.getParameterName = function(pid){
88-
return WEB_getParameterName(pid);
89-
}
96+
that.useMicrophoneInput = function () {
97+
navigator.getUserMedia.call(navigator, {audio: true}, function (stream) {
98+
var node = owl.context.createMediaStreamSource(stream);
99+
that.connectInput(node);
100+
}, function (err) {
101+
console.error(err);
102+
});
103+
}
90104

91-
that.getPatchName = function(){
92-
return WEB_getPatchName();
93-
}
105+
// Bind to Web Audio
106+
that.getParameterName = function(pid){
107+
return WEB_getParameterName(pid);
108+
}
94109

95-
that.play = function () {
96-
that.scriptProcessor.connect(owl.context.destination);
97-
that.model.playing = true;
98-
return that;
99-
};
110+
that.getPatchName = function(){
111+
return WEB_getPatchName();
112+
}
100113

101-
that.pause = function () {
102-
that.scriptProcessor.disconnect(owl.context.destination);
103-
that.model.playing = false;
104-
return that;
105-
};
114+
that.update = function (key, val) {
115+
WEB_setParameter(key, val);
116+
console.log("set parameter "+key+": "+val);
117+
return that;
118+
};
106119

107-
that.toggle = function() {
108-
if (that.model.playing) {
109-
that.pause()
110-
}
111-
else {
112-
that.play();
113-
}
114-
return that;
115-
}
120+
that.init = function () {
121+
var i;
122+
that.ptrsize = 4; // assuming pointer in emscripten are 32bits
123+
// that.vectorsize = 2048;
124+
that.samplesize = 4;
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);
145-
}
126+
// Get input / output counts
127+
that.numIn = that.getNumInputs();
128+
that.numOut = that.getNumOutputs();
146129

147-
//ptrsize, change to eight or use Runtime.QUANTUM? or what?
148-
that.outs = Module._malloc(that.ptrsize * that.numOut);
130+
// Create OWL patch web audio node
131+
that.scriptProcessor = owl.context.createScriptProcessor(that.vectorsize, that.numIn, that.numOut);
132+
that.scriptProcessor.onaudioprocess = that.compute;
149133

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-
};
134+
// Connect output of OWL processor to audio out
135+
that.scriptProcessor.connect(owl.context.destination);
157136

158-
that.init();
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);
159140

160-
return that;
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);
145+
}
146+
147+
//ptrsize, change to eight or use Runtime.QUANTUM? or what?
148+
that.outs = Module._malloc(that.ptrsize * that.numOut);
149+
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+
};
157+
158+
that.init();
159+
160+
return that;
161161
};

0 commit comments

Comments
 (0)