Add Android Oboe backend and AMY wire socket transport - #1136
Add Android Oboe backend and AMY wire socket transport#1136linuxificator wants to merge 5 commits into
Conversation
Add a fixed-size AF_UNIX/SOCK_SEQPACKET transport for local AMY wire messages, including peer credential checks, bounded queueing, cleanup safeguards, standalone regression tests, and focused CI.
Add a generic Android AAR service that renders AMY through Oboe/AAudio and accepts ordinary AMY wire packets over the private Unix transport. Include the minimal C-scale hello-world app plus Android build and emulator integration CI.
Document the generic Android AAR, Oboe backend, private SOCK_SEQPACKET client contract, readiness semantics, build requirements, and hello-world example.
Measure the raw AMY render stream and exact signed-16-bit buffer handed to Oboe during the Android hello-world integration test. Retain both WAVs and level statistics in CI, require byte-for-byte AMY-to-Oboe identity, healthy peak level, and no full-scale clipping. Use AMY V10.0 for the audible hello-world. AMY's V control is a 0..10 bus/master scale and the final mixer applies a 0.1 factor, so the previous V2.0 setting was only 20% linear gain (about -14 dB relative to V10.0). Validated at -2.721 dBFS peak with zero clipping and zero AMY-to-Oboe sample differences in Android AMY run 32630088165.
Make the Java hello-world a transport-only client. MainActivity no longer imports or starts AmyService and no longer loads a JNI/native client library. It uses Android LocalSocket SOCK_SEQPACKET directly and sends only ordinary AMY wire packets to filesDir/amy.sock. Move service startup to an AAR-owned ContentProvider lifecycle hook, remove the hello-world C++/CMake client wrapper, and move test-only audio capture arming into CI so the example remains free of service/test control logic.
|
This is great, thank you. Our sort of ad-hoc "policy" for platform/framework support (we went through the same thing with iOS) is that we won't take large framework-specific trees into the main repo. (Especially android, which me and dan can't easily test.) The android/ Gradle project, the Oboe service, the hello-world apps, the Godot Android example, and the emulator CI workflows all fall into that category — none of us develop on Android day to day, so that code would rot here. The right home for it is a separate repo (yours, or an amy-android repo we'd happily link prominently from our docs). That said, there are pieces of this work that are genuinely platform-independent and that we would like in the tree, because they make this port — and any future one — much easier:
So: would you be up for slimming this into a PR with just those pieces? We'd merge that, link your Android repo from the docs, and future Android/Godot/Qt users get the full working recipe without us carrying a platform we can't maintain. |
|
Hi, yes I can understand that maintaining it would not work without androidians. On the other hand, for me this is also just a bit of hobby in a weekend now and then, so I'm afraid the code is going to suffer the same fate as my garden and the dishes. I wonder if there are any people who need this portability from a more professional situation.. That's the thing a bit, if it is available and people would use it, it could create an incentive to maintain it. |
|
Superseded by #1147, the reduced portable-scope replacement requested in the review here. The full Android implementation remains available on the fork's upstream/android-oboe branch. |
Summary
Adds a generic Android backend for AMY:
:amyprocess;AF_UNIX/SOCK_SEQPACKETtransport at<filesDir>/amy.sock;SO_PEERCRED, socket mode0600, and a bounded 64-packet queue;The client contract is framework-independent. The hello-world application does not import or call
AmyService, does not start or stop AMY, does not load a JNI AMY client, and does not compile AMY source. It uses Android's publicLocalSocket(SOCKET_SEQPACKET)API and sends raw AMY wire packets only. The AAR owns Android service startup through its private manifestContentProvider, so the same client boundary can be used from Java/Kotlin, Godot, Qt, or another framework/language that can package the AAR and open the Unix-domain socket.The AAR intentionally remains packaged into the same Android application/UID as the client because
amy.sockis app-private (0600) and accepted peers are validated withSO_PEERCRED. That packaging requirement is separate from the client API: application/framework code has no AMY headers, source, JNI binding, or lifecycle call.Realtime design
numFramesvalues to AMY's 128-frame blocks without adding another full-block output ring.amy.sockis published only after Oboe has started and its first realtime callback has executed, so a successful socket connection is also the engine-readiness boundary.Client boundary
The Java example performs no service control. On launch it retries the private socket until it exists, then sends
v0w0V10.0Zfollowed by the C-major note-on/note-off wire packets. The previous JNI socket wrapper (libamy_hello_client.so) has been removed entirely.Validation
The contribution includes focused transport tests and Android integration/audio-level CI:
bash tests/run_amy_unix_socket_test.shvalidates packet round-trip, peer/ownership behavior, oversize handling, cleanup, and stale-path safeguards;arm64-v8aandx86_64service binaries;libamy_hello_client.soand that the hello-world module has no nativesrc/main/cppclient code;amy.sock, an output-route diagnostic,V10.0, all eight C-scale note-on packets (60, 62, 64, 65, 67, 69, 71, 72), successful completion, and no socket failure;32651283791on corrected head commita12c19bfdd9936dcb10ab8b8e39214041dd56cd9completed successfully: peak-2.721 dBFS, RMS about-7.27 dBFS, zero clipped samples, and zero AMY-to-Oboe sample differences.The audio-level regression previously caught a hello-world configuration error: AMY's
Vcontrol is a 0..10 bus/master scale and the final mixer applies a 0.1 factor. The earlier example'sV2.0therefore selected only 20% linear master gain (about -14 dB relative toV10.0). The example and documentation useV10.0.Scope
This PR remains deliberately self-contained and does not modify existing AMY core synthesis source files. The Android service contains the AMY implementation; application/framework code communicates with it only through the wire socket.
The development history is five reviewable commits, with the final commit specifically decoupling the Java hello-world from the AMY service API/JNI client and moving Android startup ownership into the AAR.