atsushieno / fluidsynth-midi-service-j

JNA-based fluidsynth MIDI device service effort
MIT License
26 stars 8 forks source link

Oboe audio driver implementation #6

Closed atsushieno closed 5 years ago

atsushieno commented 5 years ago

Now that OpenSLES is done, it's time to add support for Oboe too.

It is actually getting implemented at https://github.com/atsushieno/fluidsynth-fork/tree/oboe

atsushieno commented 5 years ago

Current stopper is Oboe symbol resolution at linker...

sources/fluidsynth-midi-service-j/external/fluidsynth/src/drivers/fluid_oboe.cpp:173: error: undefined reference to 'oboe::AudioStreamBuilder::openStream(oboe::AudioStream**)'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

If we comment out https://github.com/atsushieno/fluidsynth-fork/blob/1991318348b0433958e3a3ab210a4dd28419b1e0/src/drivers/fluid_oboe.cpp#L173 then it compiles. (How weird, we still have references to other bits of Oboe in the same source....!)

atsushieno commented 5 years ago
/sources/fluidsynth-midi-service-j/external/fluidsynth/android$ objdump -t external/oboe/build/x86/liboboe.a | grep openStream
00000000 l    d  .text._ZN4oboe18AudioStreamBuilder10openStreamEPPNS_11AudioStreamE 00000000 .text._ZN4oboe18AudioStreamBuilder10openStreamEPPNS_11AudioStreamE
00000000 g     F .text._ZN4oboe18AudioStreamBuilder10openStreamEPPNS_11AudioStreamE 00000064 _ZN4oboe18AudioStreamBuilder10openStreamEPPNS_11AudioStreamE
atsushieno commented 5 years ago

There is another (or related?) issue that some parts of the build do not specify -DANDROID_PLATFORM=android-27 or later. Oboe should be built with that target otherwise AAudio support won't be compiled.

But there is an issue where Android NDK r16 or a bit earlier builds ABI-incompatible binaries. https://github.com/android-ndk/ndk/issues/272

And our build engine Cerbero specifies r16, resulting in errors like:

jni/../dep/x86/libfluidsynth.a(fluid_oboe.cpp.o):fluid_oboe.cpp:typeinfo for oboe::AudioStreamBase: error: undefined reference to 'vtable for __cxxabiv1::__class_type_info'
/home/atsushi/android-sdk-linux/ndk-bundle/toolchains/x86-4.9/prebuilt/linux-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: the vtable symbol may be undefined because the class is missing its key function
jni/../dep/x86/libfluidsynth.a(fluid_oboe.cpp.o):fluid_oboe.cpp:typeinfo for oboe::AudioStreamBuilder: error: undefined reference to 'vtable for __cxxabiv1::__si_class_type_info'
/home/atsushi/android-sdk-linux/ndk-bundle/toolchains/x86-4.9/prebuilt/linux-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: the vtable symbol may be undefined because the class is missing its key function
jni/../dep/x86/libfluidsynth.a(fluid_oboe.cpp.o):fluid_oboe.cpp:typeinfo for oboe::AudioStreamCallback: error: undefined reference to 'vtable for __cxxabiv1::__class_type_info'
/home/atsushi/android-sdk-linux/ndk-bundle/toolchains/x86-4.9/prebuilt/linux-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: the vtable symbol may be undefined because the class is missing its key function
jni/../dep/x86/libfluidsynth.a(fluid_oboe.cpp.o):fluid_oboe.cpp:typeinfo for OboeAudioStreamCallback: error: undefined reference to 'vtable for __cxxabiv1::__si_class_type_info'
/home/atsushi/android-sdk-linux/ndk-bundle/toolchains/x86-4.9/prebuilt/linux-x86_64/lib/gcc/i686-linux-android/4.9.x/../../../../i686-linux-android/bin/ld: the vtable symbol may be undefined because the class is missing its key function
jni/../dep/x86/libfluidsynth.a(fluid_oboe.cpp.o):fluid_oboe.cpp:DW.ref.__gxx_personality_v0: error: undefined reference to '__gxx_personality_v0'
/sources/fluidsynth-midi-service-j/external/fluidsynth/src/utils/fluid_sys.c:127: error: undefined reference to 'stderr'

To workaround this issue, we will (again!) have to fork cerbero unless they upgrade to ndk r17+ (hopefully r18).

atsushieno commented 5 years ago

NDK r18 removed gcc toolchain, and it is problematic because current cerbero Android build adds "gnustl" as a dependency. This package just copies Android NDK content as the outcome, but the copy source is part of gcc. The corresponding library in clang/llvm toolchain is its libc++, but that is not a minor change.

atsushieno commented 5 years ago

Actually r17c didn't fix the issue. As Google is not going to fix any issues wrt gcc, it is not likely fixed unless Cerbero completely eliminates Android NDK gcc dependencies.

atsushieno commented 5 years ago

Now that static linking glib AND oboe is going to be non-maintaineable work, the structure should be changed like:

To make it simpler, there will be "liboboe-c.so" that is then referenced by libfluidsynth build.

atsushieno commented 5 years ago

Finally I could get libfluidsynth.so that contains Oboe support at https://github.com/atsushieno/fluidsynth-fork/commit/00ec75caba2deebe2812aa1b30a5144d3c062c1c.

Now I think r17c could build everything without oboe-c hack. It is possible that it was showing libstd ABI incompatibility because of stale builds of glib and co (I need cerbero wipe to make sure that).

atsushieno commented 5 years ago

The cause of the ABI incompatibility problem still persists. My understanding of the reason is that cerbero still builds glib with gnustl, which is GCC compatibility stack, not llvm libstdc++.

At some stage cerbero will remove gnustl hack (it seems only for Android build) and then our build can become simpler. But not now.

atsushieno commented 5 years ago

At https://github.com/atsushieno/fluidsynth-fork/commit/45fdf9d397b5659b2278ae3975c101a3fb36a62b oboe driver is successfully loaded and did not crash after note operations. Though it does not generate valid sound, need to invesitgate outputs.

atsushieno commented 5 years ago

Finally I declare that https://github.com/atsushieno/fluidsynth-fork/commit/cf4109be9e2f6c1b3684fe2885c2232ec6110849 made it working.

There are some remaining issues, but OpenSLES has the same issue too.