danomatika / ofxPd

(maintained) a Pure Data addon for OpenFrameworks using libpd
Other
201 stars 45 forks source link

Building ofxPd using Emscripten #75

Open cuinjune opened 5 years ago

cuinjune commented 5 years ago

I tried building ofxPd/pdExample project using Emscripten following this instruction: https://openframeworks.cc/setup/emscripten/

After running emmake make, it fails with the following error when it tries to build c files in libpd folder.

error: invalid argument '-std=c++14' not allowed with 'C'
shared:ERROR: compiler frontend failed to generate LLVM bitcode, halting

What should I do to fix this error? I would appreciate any advice.

P.S: I used openFrameworks-master branch since other versions have problem building Emscripten.

danomatika commented 5 years ago

What should I do to fix this error? I would appreciate any advice.

The first step is to read the error and interpret what it might mean.

openFrameworks is mostly C++ and while is libpd mostly C files. It looks like whoever made the script/makefile which builds the source files for the openFrameworks emscripten target did not test building C files as well as C++ files. The compiler seems to be saying "I can build C files, but not with the C++ stdlib." The quoted flag in the error message needs to be taken out where the compiler is being called to build the C file. I have no idea where and, as this is a general issue, I would ask the openFramneworks enscripten people.

Also, I have no idea if using libpd in emscripten will work, ie. audio in/out.

cuinjune commented 5 years ago

Thank you so much for your answer. I will report here if I succeed.

P.S: It seems like there's at least one person who could compile libpd using Emscripten: https://www.reddit.com/r/puredata/comments/8g8ahc/libpd_compiled_to_llvmwasm_has_this_been_done_or/

cuinjune commented 5 years ago

I could successfully build ofxPd/pdExample project using Emscripten.

Here are the steps I took:

  1. Open ofxPd/addon_config.mk file and remove -DLIBPD_EXTRA flag from common ADDON_CFLAGS.

  2. Remove ofxPd/libs/libpd/pure-data/extra folder.

  3. Open OF/libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk file and change PLATFORM_CFLAGS to PLATFORM_CXXFLAGS.

  4. Open ofxPd/libs/libpd/libpd_wrapper/util/ringbuffer.c and change the line 17 to the following:

    #if __STDC_VERSION__ >= 201112L && !defined(__EMSCRIPTEN__) // use stdatomic if C11 is available and emscripten is not used
  5. Open ofxPd/libs/libpd/pure-data/src/d_osc.c and change the line 19~20 to the following:

    #if defined(__linux__) || defined(__CYGWIN__) || defined(__GNU__) || \
    defined(ANDROID) || defined(__EMSCRIPTEN__)
  6. Open ofxPd/libs/libpd/pure-data/src/d_array.c and change the line 507~508 to the following:

    #if defined(__linux__) || defined(__CYGWIN__) || defined(__GNU__) || \
    defined(ANDROID) || defined(__EMSCRIPTEN__)
  7. Open ofxPd/libs/libpd/pure-data/src/x_misc.c and change the line 27 to the following:

    #if defined (__linux__) || defined (__CYGWIN__) || defined (ANDROID) || defined(__EMSCRIPTEN__)

    After these steps, I could successfully build ofxPd/pdExample project using Emscripten.

However, when I run the project on the browser, it didn't work properly. After some testings, I found out that ofSoundStream doesn't work properly on Emscripten. So I left a question on OF forum and posted an issue. I will post here again when I find a solution to fix the issue.

P.S: I accidentally found this https://mathr.co.uk/empd/#empd

cuinjune commented 4 years ago

Okay, I could almost successfully build and run ofxPd/pdExample using Emscripten.

Here are the full steps:

  1. Download openFrameworks nightly from https://openframeworks.cc/download/

  2. Download ofxPd and put it under OF/addons directory

  3. Download latest puredata src from https://github.com/pure-data/pure-data, replace the files in ofxPd/libs/libpd/pure-data/src and ofxPd/libs/libpd/pure-data/extra/pd~ folder.

  4. Download puredata src for emscripten from https://github.com/claudeha/pure-data/tree/emscripten, copy and replace d_array.c, d_osc.c, d_ugen.c, m_class.c, m_imp.h, m_pd.c, s_inter.c, x_connective.c, x_list.c, x_misc.c and x_text.c in ofxPd/libs/libpd/pure-data/src folder.

  5. Download https://github.com/claudeha/libpd/tree/emscripten and replace ofxPd/libs/libpd/libpd_wrapper and ofxPd/libs/libpd/cpp folder.

  6. Open ofxPd/libs/libpd/libpd_wrapper/util/ringbuffer.c and change the line 17 to the following:

#if __STDC_VERSION__ >= 201112L && !defined(__EMSCRIPTEN__) // use stdatomic if C11 is available and emscripten is not used

  1. Open OF/libs/openFrameworksCompiled/project/emscripten/config.emscripten.default.mk file and change PLATFORM_CFLAGS to PLATFORM_CXXFLAGS and add -s ERROR_ON_UNDEFINED_SYMBOLS=0 at the end of PLATFORM_OPTIMIZATION_LDFLAGS_RELEASE.

  2. Update ofxPd/pdExample using projectGenerator.

  3. Open ofxPd/pdExample/src/ofApp.cpp and change the line 25 to the following: #if defined(TARGET_LINUX_ARM) || defined(__EMSCRIPTEN__)

  4. Open the Terminal, cd to emscripten folder and run ./emsdk activate latest and then run source ./emsdk_env.sh.

  5. cd to ofxPd/pdExample folder and run emmake make.

  6. Once the compilation is finished, run emrun bin/pdExample.html.

And here's the screenshot:

Screen Shot 2019-08-31 at 12 18 58 PM

Although there are some errors and scope array cannot be found, I could hear the vibrato cosine wave sound and also sound from the incoming microphone which means the Pd patch opens fine at least.

Jonathhhan commented 2 years ago

Hey @danomatika, i tried to run the examples with Emscripten following the steps from @cuinjune, but without success. While it is possible to build with Emscripten (if I change the example and the patch here and there), if I use the ofxPd version that is included in OfxOfelia. It would be really great, if the official ofxPd version would be compatible with Emscripten too. Here is a discussion (there is one issue left with pd.closePatch with the ofxPd version from @cuinjune): https://github.com/openframeworks/openFrameworks/issues/6781 I can tell to you how to change the examples for Emscripten (at least pdExample and pitchShifter), if it makes sense.

danomatika commented 2 years ago

Honestly, I am never likely to use Emscripten, so it is up to y’all to make a PR where I can simply review the required changes. If you look on the pure-data Github repo itself, there is an issue about required changes for Emacripten support for the Pd sources, if you’ve not seen it already.

I prefer not to provide local hacks and would much rather accept changes made upstream, ie. libpd/pure-data, so I suggest starting there and working back toward here.

enohp ym morf tnes

Dan Wilcox danomatika.com robotcowboy.com

On Nov 23, 2021, at 4:02 PM, Jonathan @.***> wrote:

 Hey @danomatika, i tried to run the examples with Emscripten following the steps from @cuinjune, but without success. While it is possible to build with Emscripten (if I change the example and the patch here and there), if I use the ofxPd version that is included in OfxOfelia. It would be really great if the official ofxPd version would be compatible with Emscripten too. Here is a discussion (there is one issue left with pd.closePatch with the ofxPd version from @cuinjune). Here is a discussion: openframeworks/openFrameworks#6781

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

Jonathhhan commented 4 months ago

@danomatika I guess this issue can be closed, because compiling with Emscripten is possible without any changes now.

danomatika commented 4 months ago

Please test the develop branch. It includes prelim pd 0.55 sources as well as updates to the scripts to allow for easier testing of libpd versions: https://github.com/danomatika/ofxPd/tree/develop?tab=readme-ov-file#trying-newer-versions-of-libpd

I don't normally use a develop branch here but this warrants additional testing in case we need to fix anything inside the Pd core itself.

Jonathhhan commented 4 months ago

@danomatika tested the pdExample with Emscripten and it works well. There are a few things that I had to change in the patch (which was also the case with earlier attempts): [array] needs to be replaced with [array define] and [midiout], [midiin] and [sysexin] do not work and need to be removed. Those changes need to be made, otherwise the patch does not work at all. Here is the edited patch: test.zip

danomatika commented 4 months ago

@danomatika tested the pdExample with Emscripten and it works well. There are a few things that I had to change in the patch (which was also the case with earlier attempts): [array] needs to be replaced with [array define] and [midiout], [midiin] and [sysexin] do not work and need to be removed. Those changes need to be made, otherwise the patch does not work at all. Here is the edited patch: test.zip

I'm not willing to change the default example/test patch. What do you mean by "do not work" ie. does the app crash or does the patch simply do nothing?

Jonathhhan commented 4 months ago

I'm not willing to change the default example/test patch.

Thats not what I wanted to say. I wanted to say that it is expected behavior that the pdExample does not work with Emscripten as it is (which is not a problem for me). And tell what need to be theoretically(!) changed. ofxPd works well with Emscripten now (as far as I can tell), which is very nice.

The app does nothing and this is the error message:

Uncaught RuntimeError: null function or function signature mismatch
    at index.wasm.pd_typedmess (http://localhost:6931/index.wasm:wasm-function[306]:0x1b9a4)
    at index.wasm.binbuf_eval (http://localhost:6931/index.wasm:wasm-function[320]:0x1c863)
    at index.wasm.binbuf_evalfile (http://localhost:6931/index.wasm:wasm-function[2009]:0xcb758)
    at index.wasm.glob_evalfile (http://localhost:6931/index.wasm:wasm-function[1248]:0x6c2b3)
    at index.wasm.libpd_openfile (http://localhost:6931/index.wasm:wasm-function[1861]:0xadaa3)
    at index.wasm.ofxPd::openPatch(std::__2::basic_string<char, std::__2::char_traits<char>, std::__2::allocator<char>> const&) (http://localhost:6931/index.wasm:wasm-function[1729]:0x96cd6)
    at index.wasm.ofApp::setup() (http://localhost:6931/index.wasm:wasm-function[3529]:0x126d8e)
    at index.wasm.ofNode::onParentOrientationChanged(glm::qua<float, (glm::qualifier)0>&) (http://localhost:6931/index.wasm:wasm-function[1765]:0xa0497)
    at index.wasm.std::__2::__function::__func<std::__2::shared_ptr<of::priv::Function<ofKeyEventArgs, std::__2::recursive_mutex>> ofEvent<ofKeyEventArgs, std::__2::recursive_mutex>::make_function<ofMainLoop>(ofMainLoop*, void (ofMainLoop::*)(ofKeyEventArgs&), int)::'lambda'(void const*, ofKeyEventArgs&), std::__2::allocator<std::__2::shared_ptr<of::priv::Function<ofKeyEventArgs, std::__2::recursive_mutex>> ofEvent<ofKeyEventArgs, std::__2::recursive_mutex>::make_function<ofMainLoop>(ofMainLoop*, void (ofMainLoop::*)(ofKeyEventArgs&), int)::'lambda'(void const*, ofKeyEventArgs&)>, bool (void const*, ofKeyEventArgs&)>::operator()(void const*&&, ofKeyEventArgs&) (http://localhost:6931/index.wasm:wasm-function[579]:0x2fd4b)
    at index.wasm.ofEvent<ofEventArgs, std::__2::recursive_mutex>::notify(ofEventArgs&) (http://localhost:6931/index.wasm:wasm-function[819]:0x43ad5)
danomatika commented 4 months ago

Seems like a bug then... I would expect the app to maybe not work but at least not crash. That is the point of the patch: as a test as well a showing basic functionality.

Jonathhhan commented 4 months ago

So the problematic PD objects with Emscripten are (so far): [array], [midiout], [midiin] and [sysexin].

danomatika commented 4 months ago

For the last three, it might need to be built with s_midi_dummy.c instead of s_libpdmidi.c or the libpd part should be disabled via an ifdef for EMSCRIPTEN.enohp ym morf tnes-----------Dan Wilcoxdanomatika.comrobotcowboy.comOn Apr 11, 2024, at 1:01 AM, Jonathan Frank @.***> wrote: So the problematic PD objects with Emscripten are [array], [midiout], [midiin] and [sysexin].

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>

Jonathhhan commented 4 months ago

I made a webMIDI proposal for OF some time ago, which works quite well: https://github.com/openframeworks/openFrameworks/pull/7259 Not sure, if it would make sense to integrate webMIDI into libpd somehow at some point or leave it as a seperate solution.

I get this error when I replace s_libpdmidi.c with s_midi_dummy.c:

wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/m_glob.o: undefined symbol: glob_midi_setapi
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/m_glob.o: undefined symbol: glob_midi_properties
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/m_glob.o: undefined symbol: glob_midi_dialog
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/s_main.o: undefined symbol: sys_gui_midipreferences
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_byte
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_byte
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_byte
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_noteon
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_noteon
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_controlchange
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_controlchange
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_programchange
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_pitchbend
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_aftertouch
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_aftertouch
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_polyaftertouch
wasm-ld: error: /mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/addons/obj/emscripten/Release/ofxPD/libs/libpd/pure-data/src/x_midi.o: undefined symbol: outmidi_polyaftertouch
em++: error: '/mnt/c/Users/Jonat/emsdk/upstream/bin/wasm-ld @/tmp/emscripten_kihhsndn.rsp.utf-8' failed (returned 1)
make[1]: *** [/mnt/c/Users/Jonat/Desktop/openFrameworks-audioWorklet-3/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk:406: bin/pdExample/index.html] Error 1
danomatika commented 4 months ago

I get this error when I replace s_libpdmidi.c with s_midi_dummy.c

Then this is probably not the right approach to fix this. Sending a message from Pd through a midi object just results in the appropriate midi hook function getting called. There is no built-in midi library, so this should not trigger a crash. It's a bug.

I would ask @claudeha or @Spacechild1 about this since now is the time to test, find bugs, and fix them if you want the fixes in pure-data or libpd any time soon...

claudeha commented 4 months ago

On 11/04/2024 08:35, Dan Wilcox wrote:

There is no built-in midi library, so this should not trigger a crash. It's a bug.

I would ask @claudeha https://github.com/claudeha or @Spacechild1 https://github.com/Spacechild1 about this since /now/ is the time to test, find bugs, and fix them if you want the fixes in pure-data or libpd any time soon...

See https://github.com/libpd/libpd/pull/395 , I haven't tested any WebMIDI API or similar. Emscripten is stricter about casting function pointers (they must be called at the exact original type), which is the reason for the original runtime failure.