emscriptenopenframeworks

Can't hear sound using ofSoundStream on Emscripten


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. enter image description here

In the Javascript console, I get the following error message:

Uncaught TypeError: Runtime.dynCall is not a function at ScriptProcessorNode.stream.onaudioprocess

enter image description here

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?


Solution

  • 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.