I found out ofSoundStream
based examples don't work properly on Emscripten.
Here' my minimal example code that works on macOS but doesn't work on Emscripten.
ofApp.h
:
#pragma once
#include "ofMain.h"
class ofApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y);
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
void audioOut(ofSoundBuffer & buffer); //only this is added
};
ofApp.cpp
: (only relevant methods)
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup(){
ofSoundStreamSettings settings;
settings.numInputChannels = 0;
settings.numOutputChannels = 2;
settings.sampleRate = 44100;
settings.bufferSize = 512;
settings.setOutListener(this);
ofSoundStreamSetup(settings);
}
//--------------------------------------------------------------
void ofApp::audioOut(ofSoundBuffer & buffer)
{
for (size_t i = 0; i < buffer.getNumFrames(); ++i)
{
buffer[i*buffer.getNumChannels() ] = ofRandom(0, 1) * 0.1;
buffer[i*buffer.getNumChannels() + 1] = ofRandom(0, 1) * 0.1;
}
}
Result: When I run it, it says Exception thrown, see JavaScript console
.
In the Javascript console, I get the following error message:
Uncaught TypeError: Runtime.dynCall is not a function at ScriptProcessorNode.stream.onaudioprocess
In the Terminal console, I get no specific message. And of course, I hear no sound at all.
I found out ofxEmscriptenSoundStream::audio_cb()
function is not being called at all although its function pointer is passed to html5audio_stream_create()
function when ofxEmscriptenSoundStream::setup()
is called.
html5audio_stream_create
function is implemented in library_html5audio.js
file and I think the following part is where it calls the ofxEmscriptenSoundStream::audio_cb()
function:
Runtime.dynCall('viiii',callback,[bufferSize,inputChannels,outputChannels,userData]);
However I have no idea why it fails to call the callback function. (I can't code JS)
How can I make ofSoundStream
properly work on Emscripten?
I could fix this issue by changing Runtime.dynCall
to just dynCall
in library_html5audio.js
file.
I followed the advice from this post:
The Runtime object has been removed for quite some time at this point (to fix that issue, you should remove Runtime. from your code, and just call dynCall).
After the fix and rebuilding the project, I could successfully hear the sound on a Chrome browser.