{"id":13730627,"url":"https://github.com/atsushieno/aap-juce","last_synced_at":"2025-04-21T20:32:36.435Z","repository":{"id":48998003,"uuid":"247669577","full_name":"atsushieno/aap-juce","owner":"atsushieno","description":"AAP (Audio Plugins For Android) JUCE integration.","archived":false,"fork":false,"pushed_at":"2025-04-09T09:12:01.000Z","size":521,"stargazers_count":16,"open_issues_count":14,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-09T09:40:47.919Z","etag":null,"topics":["aap","aap-juce","android-audio","audio","audio-plugin","juce","juce-android"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atsushieno.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-16T10:09:41.000Z","updated_at":"2025-04-09T09:12:05.000Z","dependencies_parsed_at":"2023-11-21T05:36:44.798Z","dependency_job_id":"bf01650d-6626-4b8c-bb42-c8a445c06cb0","html_url":"https://github.com/atsushieno/aap-juce","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faap-juce","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faap-juce/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faap-juce/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atsushieno%2Faap-juce/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atsushieno","download_url":"https://codeload.github.com/atsushieno/aap-juce/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250128354,"owners_count":21379493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aap","aap-juce","android-audio","audio","audio-plugin","juce","juce-android"],"created_at":"2024-08-03T02:01:17.353Z","updated_at":"2025-04-21T20:32:36.422Z","avatar_url":"https://github.com/atsushieno.png","language":"C","funding_links":[],"categories":["Integrations"],"sub_categories":[],"readme":"# AAP-JUCE: JUCE audio plugin and hosting support for AAP (Audio Plugins For Android)\n\nThis repo is the place where we have the common JUCE integration support modules for [aap-core](https://github.com/atsushieno/aap-core) (AAP), for both plugins and hosts.\n\nThe entire AAP framework is on early development phase and not ready for any serious consumption yet.\nEverything is subject to change. Contributions are welcome but please bear in mind, documentation is poor and source code is ugly yet. We have GitHub discussions for AAP enabled at [aap-core](https://github.com/atsushieno/aap-core/discussions/landing) so please feel free to shoot your questions, if any.\n\n## Existing ports\n\nThis repository used to contain a handful of sample projects, but to avoid bloat core library repository, they are split from here and have their own repositories. Now they are listed at [AAP Wiki](https://github.com/atsushieno/aap-core/wiki/List-of-AAP-plugins-and-hosts).\n\naap-juce-plugin-host can enumerate the installed AAP plugins on the system (not limited to aap-juce ones), and instantiate each plugin.\n\nAt this state, this repository itself is almost only about a set of build scripts that lets you port your (or others') JUCE audio plugins and hosts to AAP world. And probably more importantly, this README.\n\n## Why JUCE for AAP?\n\nJUCE is a popular cross-platform, multi-plugin-format audio development framework.\nJUCE itself does not support AAP, but it can be extended by additional modules.\nJUCE also supports Android (you can even run UI), which makes things closer to actual app production.\nStill, JUCE is not designed to be extensible *enough*, additional code to support AAP is needed in each app.\n\nWhile JUCE itself is useful to develop plugin formats like AAP, it is designed to be independent of any other audio development toolkits and frameworks. We stick to minimum dependencies, at least on the public API surface.\n\nJUCE API is stable-ish, while AAP API is not. So if anyone wants to get audio plugins portable without fear of API breakage, JUCE can be your good friend.\n\nNote that JUCE plugins are usually designed for desktop and not meant to be usable on mobiles. In particular -\n\n- their UIs are usually useless on mobile.\n- those plugins that lets user pick up local files would not fit well with Android paradigm.\n- Some plugins would expose performance issues too.\n\n## How to try it out?\n\nYou would have to build and install each host and/or plugin from source so far, or look for the APKs from the build artifacts zip archives from successful GitHub Actions workflow runs. They could be installed via [AAP APK Installer](https://github.com/atsushieno/aap-ci-package-installer). Note that not all plugins are updated and there can be incompatible AAP protocol versions of the plugins, or outdated to not work properly on newer Android platforms.\n\nYou need a host app and a plugin to try at least one plugin via one host. This repository does not contain any application within itself.\n\nThe host can be either `aaphostsample` in aap-core repo, a project [aap-juce-simple-host](https://github.com/atsushieno/aap-juce-simple-host) that is somewhat tailored for AAP and mobile UI, or `AudioPluginHost` in [aap-juce-plugin-host-cmake](https://github.com/atsushieno/aap-juce-plugin-host) repo (which is JUCE AudioPluginHost with AAP support).\n\nThe plugin can be either `aappluginsample` in aap-core repo (more stable), or any plugin on the [AAP Wiki](https://github.com/atsushieno/aap-core/wiki/List-of-AAP-plugins-and-hosts).\n\nFor those `aap-juce-*` repositories, `make` will build them. (`Makefile` does not sound cool, but it is at least distinct from `CMakeLists.txt` for Android app itself...)\n\nFor JUCE apps that use Projucer, JUCE Android apps are generated and built under `Builds/Android/app/build/outputs/` in each app directory.\nThough we typically use Android Studio and open `Builds/Android` and then run or debug there, once top-level `make` ran successfully.\n\nFor those projects that use CMake, it is `app/build/outputs`.\n\n\n## App Build Instruction\n\n### CI builds\n\naap-juce itself is a set of JUCE modules that itself does not \"build\". But still, there are [reusable GitHub Actions workflows](https://docs.github.com/en/actions/using-workflows/reusing-workflows) under `.github` directory: one for CMake based projects and another for Projucer based projects. They are kind of normative build instructions (in that it is offered by ourselves).\n\nThe actual build is one `make` call if all conditions are met. In other words, every project that uses the workflow is adjusted to build with that.\n\nAs long as other project follows the same structure, you can reuse it too. It is safe to use the versioned workflow by commit rev. as we will be making breaking changes.\n\n### Building locally\n\nAs a prerequisite, you need Android SDK. If you install it via Android Studio it is usually placed under `~/Android/Sdk` on Linux, and `~/Library/Android/sdk` on MacOS.\nYou also need Android NDK, most likely at least r23 (our latest development version uses newer ones).\n\nFor those project that use Projucer: depending on the NDK setup you might also have to rewrite `Makefile` and `Builds/Android/local.properties` to point to the right NDK location. Then run `cd Builds/Android \u0026\u0026 ./gradlew build` instead of `./projuce-app.sh`.\nIt would be much easier to place Android SDK and NDK to the standard location though. Symbolic links would suffice.\n\nCMake based projects would similarly need to tweak `Makefile`, but other than that it is a typical Android Studio (Android Gradle) project.\n\n## Additional notes on Projucer\n\naap-juce basically recommends CMake for porting JUCE plugins to Android, but it is still technically possible to use Projucer-based projects for porting.\n\nSince Projucer support needs quite a lot of more documentation, we have consolidated Projucer-related topics to [docs/PROJUCER.md](docs/PROJUCER.md) to keep this document cleaner.\n\n## Porting a plugin or a host to AAP\n\nTo port existing plugins, or even with a new project, you will either follow the CMake way, or the Projucer way.\nYou would normally have no choice, the original project would be either of those already, but CMake is much easier and much more intuitive to deal with. With Projucer, you will have to generate project every time you make changes to the project.\nIn either approach, you end up with an Android Studio (Gradle) project that you can open on Android Studio (or stick to Gradle to build and adb to install, like we do on CI).\n\nThere are many aap-juce based apps that could be used as reference/template projects. See the list of plugins on the AAP Wiki.\n\n### Patching\n\nIn most aap-juce-* apps, I created `aap-juce-support.patch` that (for each app) contains a set of changes as in patch files. In `Makefile`, there is `PATCH_FILE` variable that indicates one single patch file. It usually points to that `aap-juce-support.patch`.\n\nIF the build system is Projucer, there is an additional variable called `PATCH_DEPTH` which is used with `patch` tool as: `patch -i [aap-juce-support.patch] -p [PATCH_DEPTH]`. For CMake projects -p 1 should suffice so I used `git apply` which does not take patch depth instead.\n\n### Making application itself build for Android\n\nIf you are trying to port an existing project to Android, the first thing to do is to make it build for Android, regardless of AAP.\nIf it is a Projucer project, open Projucer, add Android Studio exporter, resave, open on Android Studio and try to build.\nIf it is a CMake project, check the next  section (\"Make AAP-specific changes: CMake\").\n\nJUCE API is in general less featureful on Android than desktop. For example, you have no access to synchronous dialog boxes.\nSo you will have to rewrite code to follow asynchronous way or disable code so far. Once it's done, let's mark it as **the** porting target application.\n (They were deprecated in recent JUCE versions in 2021, so newer projects would suffer less.)\n\n### Make AAP-specific changes: CMake\n\nFor a project that build with CMake, it is fairly easier to port to AAP.\n\nThere are existing sample projects listed earlier on our [AAP wiki page](https://github.com/atsushieno/aap-core/wiki/List-of-AAP-plugins-and-hosts), and to port an existing plugin project (or even if you are going to create a new JUCE plugin project), it is easier to create new project based off of those existing ones, making changes to your plugin specifics. For details, see [docs/PLUGIN_PORTING_GUIDE.md](docs/PLUGIN_PORTING_GUIDE.md).\n\nThere are some important bits:\n\n- JUCE needs some changes. [JUCE-support-Android-CMake.patch](JUCE-support-Android-CMake.patch) is applied if you build those ports with `make`.\n- The plugin's top level `CMakeLists.txt` : we need `Standalone` plugin build (as no other formats are supported, and on Android it is built as a shared library). We also (typically) patch this file to add build setup for AAP specifics.\n- `app/src/main/cpp`: is typically a symbolic link to the JUCE plugin app source (e.g. `cpp` -\u003e `../../../external/dexed`).\n\nA typical porting trouble we encounter is that even if the activity launches, it shows an empty screen.\nIt is because the application somehow fails to bootstrap (call to `com.rmsl.juce.Java.initialiseJUCE()`).\n\nAnother typical problem is that it fails to load the plugin shared library. It is due to missing shared library within the apk, inconsistent `aap_metadata.xml` description (either `library` or `entrypoint` attribute), or missing entrypoint function symbol in the shared library (which must not be `visibility=hidden`).\n\n\n### Creating aap_metadata.xml\n\nStarting aap-core 0.7.7 along with its parameters extension v2.1, it supports dynamic parameter population by code, and aap-juce fully makes use of it. This feature makes `aap_metadata.xml` simply editable by human beings i.e. you can just copy existing `aap_metadata.xml` from other project and replace \"names\" in it.\n\nIt used to be \"generated automatically\". The next section explained that, but it is totally passable anymore.\n\n### Generating and updating aap_metadata.xml\n\nNOTE: this only applies to aap-juce 0.4.8 or earlier. The generator is not part of the build anymore. You can however still try to build and use it by making changes to aap-juce codebase. The build tasks in [the old `Makefile.common`](https://github.com/atsushieno/aap-juce/blob/135477ef53b1e6585463eebb92d5e06db62674e9/Makefile.common#L191) and [`generate-metadata.sh`](https://github.com/atsushieno/aap-juce/blob/135477ef53b1e6585463eebb92d5e06db62674e9/generate-metadata.sh#L1) would be helpful.\n\nThis only applies to plugins (hosts do not need it).\n\n`aap_metadata.xml` has to be created for the plugin.\n\nStarting aap-juce 0.4.7, we do not really have to \"generate\" it automatically - we could just copy some `aap_metadata.xml` and modify it to match your project (especially, names and the native library filename). Therefore, we deprecate the following paragraphs.\n\n\u003cdel\u003e\nThere is some non-trivial task: `aap_metadata.xml` has to be created for the plugin. Sometimes it can be hundreds of lines of markup, so you would like to automatically generate from existing code.\n\u003c/del\u003e\n\n\u003cdel\u003e\nThere is `update-aap-metadata` target in `Makefile.common` or `update-aap-metadata-cmake` target in `Makefile.cmake-common`, but in case you would like to run it manually...\n\u003c/del\u003e\n\n\u003cdel\u003e\nTo import JUCE audio plugins into AAP world, we have to create plugin\ndescriptor (`aap_metadata.xml`). We have a supplemental tool source to\nhelp generating it automatically from JUCE plugin binary (shared code).\n\u003c/del\u003e\n\n### Dealing with different JUCE versions\n\nJUCE sometimes involves incompatible changes between versions, and sometimes they involve those project file generators. We have some Makefile variables that changes the behavior. It is worth inspecting `Makefile.common` for Projucer-based project and `Makefile.cmake-common` for CMake-based projects (they are often added).\n\n\n## Under the hood\n\nJUCE itself already supports JUCE apps running on Android and there is still no need to make any changes to the upstream JUCE, unless you want to build CMake based project (see [this post by @atsushieno](https://atsushieno.github.io/2021/01/16/juce-cmake-android-now-works.html) for details).\n\nOn the other hand, we make a lot of changes to whatever Projucer generates.\nProjucer is not capable of supporting arbitrary plugin format and it's quite counter-intuitive to try to use various option fields on Projucer.\nThus we simply replace various parts of the generated Android Gradle project.\nIt is mostly taken care by `projuce-app.sh`.\n\nCMake is preferred, but it is not officially supported by JUCE so far either.\nHowever the impact of the changes is small so that they can be manually fixed.\n\nWe plan to juce_emscripten for future integration with wasm UI builds.\n\n### difference between normal JUCE Android app and JUCE-AAP Android app\n\nWe have a lot of works for Projucer-based projects here, but things are much simpler for CMake support. We simply use our own app template with slight changes and reference to `CMakeLists.txt` from the app that is being ported.\n\n### GUI limitation\n\naap-core since 0.7.7 provides preliminary native plugin-process GUI functionality, but since JUCE GUI does not work as a standalone `View`, unlike Jetpack Compose,or Flutter, it is impossible to reuse existing desktop UI at the moment. JUCE plugins even invalidates whatever `Activity` we specify at `AndroidManifest.xml` and launches its own `JuceActivity` instead. It is a brutal behavior, but we cannot fix without a various patching effort.\n\nAt the moment, you are encouraged to build a dedicated mobile UI for JUCE based plugins, without `juce_gui_basics`. Or push JUCE team to improve their GUI support to make it just work as `View`.\n\n\n## Using AddressSanitizer on aap-juce apps\n\nIt is tricky to set up ASAN for aap-juce apps, especially for those projects that use Projucer (as it regenerates the projects every time you re-save .jucer).\n\nThe easiest way would be to copy `setup-asan-for-debugging.sh` to `(app)/Builds/Android/` directory, modify the script to have `ALL_APPS` variable to point to `app` directory, and run it there. For CMake-based projects, it can be just the top directory (and point to the source as well).\n\nThen you have to make some changes to the build scripts (`build.gradle(.kts)` and `CMakeLists.txt`) to take those options. You can track how `enable_asan` variable in `aap-core` repository is used.\n\nThere is one more change needed: Projucer generates CMake arguments to contain `-DANDROID_STL_c++_static`. It has to be changed to `-DANDROID_STL=c++_shared`.\n\nNote that if you are on Projucer based project, Projucer will clean up all your efforts every time it resaves the project.\n\n## Profiling\n\nBoth `aap_audio_plugin_client` and `aap_audio_processors` implement profiling support using ATrace API, just like aap-core and aap-lv2 do. The profiling is done at both including and excluding aap-juce specific parts.\n\nFor more details on AAP tracing, read the [aap-core documentation](https://github.com/atsushieno/aap-core/blob/e9a28aa7f382a0c30b8b378b6809d2effa25e002/docs/DEVELOPERS.md#profiling-audio-processing) (it is a permalink; there may be updated docs).\n\n## Code origin and license\n\nThis repository itself is licensed under the GPLv3 license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatsushieno%2Faap-juce","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatsushieno%2Faap-juce","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatsushieno%2Faap-juce/lists"}