Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add Android cdylib build support

Gate Java-shell Android sources behind CODECS_STATIC so the cdylib
build uses small headless stubs instead of JNI/Java files. Add
cdylib-specific hosted pieces (system-android, pcm-aaudio, lc-android,
lcd/button no-ops, adc-target.h) and minor rb_zig_compat fixes.

Skip the cRSID codec on NDK clang builds. tools/configure now exports
CODECS_STATIC and -DZIG_APP for Android ndk builds; sigevent_t is
provided via a compile-time -D instead of a typedef in config.h.

+74 -50
+6 -2
apps/SOURCES
··· 99 99 gui/splash.c 100 100 gui/statusbar.c 101 101 gui/statusbar-skinned.c 102 - #if (CONFIG_PLATFORM&PLATFORM_ANDROID) 102 + #if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined(CODECS_STATIC) 103 103 hosted/android/yesno.c 104 104 hosted/android/notification.c 105 105 #else ··· 123 123 124 124 recorder/bmp.c 125 125 recorder/icons.c 126 - #if (CONFIG_PLATFORM&PLATFORM_ANDROID) 126 + #if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined(CODECS_STATIC) 127 127 hosted/android/keyboard.c 128 128 #else 129 129 recorder/keyboard.c ··· 244 244 #elif CONFIG_KEYPAD == MPIO_HD300_PAD 245 245 keymaps/keymap-mpio-hd300.c 246 246 #elif CONFIG_KEYPAD == ANDROID_PAD 247 + #if !defined(CODECS_STATIC) 248 + /* keymap-android.c references BUTTON_DPAD_* constants from the Java-shell 249 + * Android target's button-target.h. Our cdylib has no buttons. */ 247 250 keymaps/keymap-android.c 251 + #endif 248 252 #elif CONFIG_KEYPAD == SDL_PAD 249 253 keymaps/keymap-sdl.c 250 254 #elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
+1 -1
apps/root_menu.c
··· 840 840 841 841 static void ignore_back_button_stub(bool ignore) 842 842 { 843 - #if (CONFIG_PLATFORM&PLATFORM_ANDROID) 843 + #if (CONFIG_PLATFORM&PLATFORM_ANDROID) && !defined(CODECS_STATIC) 844 844 /* BACK button to be handled by Android instead of rockbox */ 845 845 android_ignore_back_button(ignore); 846 846 #else
+10 -4
firmware/SOURCES
··· 14 14 powermgmt.c 15 15 #if (CONFIG_PLATFORM & PLATFORM_HOSTED) 16 16 17 - #ifdef __linux__ 17 + #if defined(__linux__) && !defined(__ANDROID__) 18 + /* bionic doesn't ship cpu-features.h in its default include paths, and our 19 + * cdylib doesn't need cpu-info introspection from the engine. */ 18 20 target/hosted/cpuinfo-linux.c 19 21 target/hosted/cpufreq-linux.c 20 22 #endif ··· 1979 1981 target/hosted/filesystem-unix.c 1980 1982 1981 1983 #if defined(CODECS_STATIC) 1982 - /* cdylib build — files come from target/hosted/android/cdylib/SOURCES via 1983 - * cdylib.make's OTHER_SRC append. The legacy Java-shell files reference 1984 - * jni.h and Java callbacks that we don't have. */ 1984 + /* cdylib build — headless, AAudio, BINFMT_STATIC. */ 1985 + target/hosted/android/cdylib/system-android.c 1986 + target/hosted/android/cdylib/pcm-aaudio.c 1987 + target/hosted/android/cdylib/lc-android.c 1988 + target/hosted/android/cdylib/rb_zig_compat.c 1989 + target/hosted/android/cdylib/lcd-noop.c 1990 + target/hosted/android/cdylib/button-noop.c 1985 1991 #else 1986 1992 /* Existing Java-shell Android app */ 1987 1993 target/hosted/lc-unix.c
+5 -7
firmware/export/config/androidcdylib.h
··· 65 65 66 66 #define AB_REPEAT_ENABLE 67 67 68 - /* bionic only declares `struct sigevent` (POSIX). Rockbox's kernel-unix.c 69 - * uses the glibc-style `sigevent_t` typedef. Provide it once here so we 70 - * don't have to patch shared firmware code. */ 71 - #ifndef __ASSEMBLER__ 72 - #include <signal.h> 73 - typedef struct sigevent sigevent_t; 74 - #endif 68 + /* `sigevent_t` (glibc-style typedef used by kernel-unix.c) is provided as 69 + * a -D macro in androidcdylibcc rather than typedef'd here — putting code 70 + * in config.h would leak into the output of `preprocess` (which uses 71 + * -include config.h to evaluate SOURCES files) and produce nonsense make 72 + * targets. -D makes the substitution at compile time only. */
+10 -2
firmware/export/lc-static.h
··· 10 10 #ifndef __LC_STATIC_H__ 11 11 #define __LC_STATIC_H__ 12 12 13 + #include "system.h" 13 14 #include <stddef.h> 14 15 16 + /* Same surface as lc-dlopen.h — same callers (apps/codecs.c, plugin loader) 17 + * and same return-value semantics (NULL on failure). Implemented in 18 + * firmware/target/hosted/android/cdylib/lc-android.c against a compile-time 19 + * codec table. */ 20 + void *lc_open(const char *filename, unsigned char *buf, size_t buf_size); 21 + void *lc_get_header(void *handle); 22 + void lc_close(void *handle); 23 + 15 24 struct codec_header; /* forward; full def in lib/rbcodec/codecs/codecs.h */ 16 25 17 26 struct lc_static_entry { ··· 19 28 const struct codec_header *hdr; 20 29 }; 21 30 22 - /* Generated table; defined in firmware/target/hosted/android/cdylib/ 23 - * codec_table.c by the codecs.make CODECS_STATIC mode. NULL-terminated. */ 31 + /* Generated table; for now defined in lc-android.c. NULL-terminated. */ 24 32 extern const struct lc_static_entry lc_static_table[]; 25 33 26 34 #endif /* __LC_STATIC_H__ */
+1
firmware/target/hosted/android/cdylib/adc-target.h
··· 1 + /* Empty stub — no ADC on Android cdylib (battery info comes from JS via JNI). */
+9
firmware/target/hosted/android/cdylib/lc-android.c
··· 10 10 11 11 #include "load_code.h" /* pulls lc-static.h via CONFIG_BINFMT dispatch */ 12 12 13 + /* Empty placeholder table — will be replaced by an auto-generated 14 + * codec_table.c (or by extern decls + an array literal here) once the 15 + * cdylib link step actually pulls per-codec .a files in. For now lc_open 16 + * returns NULL for everything, which makes the engine fall back to its 17 + * "no codec found" path. The build links cleanly. */ 18 + const struct lc_static_entry lc_static_table[] = { 19 + { (const char *)0, (const struct codec_header *)0 } 20 + }; 21 + 13 22 void *lc_open(const char *filename, unsigned char *buf, size_t buf_size) 14 23 { 15 24 (void)buf;
+1 -1
firmware/target/hosted/android/cdylib/lcd-noop.c
··· 5 5 * everything's discarded since there's no display. 6 6 * 7 7 * This file is grown iteratively as the linker reveals more unresolved 8 - * lcd_*/backlight_* symbols. Start tight, add as needed. 8 + * lcd_ / backlight_ symbols. Start tight, add as needed. 9 9 */ 10 10 11 11 #include <stdbool.h>
+7 -12
firmware/target/hosted/android/cdylib/pcm-aaudio.c
··· 77 77 AAudioStreamBuilder_setFormat (b, AAUDIO_FORMAT_PCM_I16); 78 78 AAudioStreamBuilder_setChannelCount (b, 2); 79 79 AAudioStreamBuilder_setSampleRate (b, freq); 80 - AAudioStreamBuilder_setUsage (b, AAUDIO_USAGE_MEDIA); 81 - AAudioStreamBuilder_setContentType (b, AAUDIO_CONTENT_TYPE_MUSIC); 80 + /* setUsage / setContentType are API 28+ — metadata only, skip on API 26 81 + * to keep the minSdk floor low. AAudio defaults to MEDIA / MUSIC anyway. */ 82 82 AAudioStreamBuilder_setErrorCallback (b, on_error, NULL); 83 83 84 84 rc = AAudioStreamBuilder_openStream(b, &aa_stream); ··· 145 145 continue; 146 146 } 147 147 148 - if (size > aa_vol_buf_cap) { 149 - free(aa_vol_buf); 150 - aa_vol_buf = malloc(size); 151 - aa_vol_buf_cap = aa_vol_buf ? size : 0; 152 - } 153 - const void *data = (aa_vol_buf && size > 0) 154 - ? (pcm_copy_buffer(aa_vol_buf, raw, size), aa_vol_buf) 155 - : raw; 156 - if (data == aa_vol_buf) 157 - pcm_normalizer_apply(aa_vol_buf, size); 148 + /* SW volume scaling skipped on Android — AAudio + Java MediaSession 149 + * handle volume system-side. Just write the raw PCM through. */ 150 + const void *data = raw; 151 + (void)aa_vol_buf; 152 + (void)aa_vol_buf_cap; 158 153 159 154 const uint8_t *p = (const uint8_t *)data; 160 155 size_t bytes_left = size;
+4 -8
firmware/target/hosted/android/cdylib/rb_zig_compat.c
··· 21 21 #include "metadata.h" 22 22 23 23 /* ── Playlist wrappers — port of zig/src/rockbox/playlist.zig ──────────── */ 24 - 25 - struct playlist_track_info { 26 - char filename[260]; 27 - int attr; 28 - int index; 29 - int display_index; 30 - }; 24 + /* struct playlist_track_info is declared in apps/playlist.h (above). */ 31 25 32 26 struct playlist_track_info rb_get_track_info_from_current_playlist(int index) 33 27 { ··· 86 80 int rb_playlist_insert_directory(const char *dir, int position, 87 81 bool queue, bool recurse) 88 82 { 83 + /* The 6th arg is a struct playlist_insert_context*; NULL means "no 84 + * progress reporting", which matches the Zig wrapper's behavior. */ 89 85 return playlist_insert_directory(playlist_get_current(), 90 - dir, position, queue, recurse); 86 + dir, position, queue, recurse, NULL); 91 87 } 92 88 93 89 int rb_playlist_remove_all_tracks(void)
+8 -13
firmware/target/hosted/android/cdylib/system-android.c
··· 20 20 #include <stdbool.h> 21 21 #include <android/log.h> 22 22 23 + #include "config.h" 23 24 #include "system.h" 24 25 #include "kernel.h" 25 26 #include "panic.h" ··· 52 53 53 54 /* ── Power off / reboot / exception wait ──────────────────────────────── */ 54 55 55 - void sdl_sys_quit(void) /* kept for symbol compatibility with apps/ callers */ 56 - { 57 - quitting = true; 58 - sys_poweroff(); 59 - } 60 - 61 56 void power_off(void) 62 57 { 63 58 LOGI("power_off requested"); ··· 65 60 quitting = true; 66 61 pthread_cond_broadcast(&shutdown_cv); 67 62 pthread_mutex_unlock(&shutdown_lock); 68 - sim_do_exit(); 69 - } 70 - 71 - void sim_do_exit(void) 72 - { 73 - sim_kernel_shutdown(); 63 + /* Just exit the process — JNI's rb_daemon_stop pthread_joins the engine 64 + * thread and observes the exit. No SDL/sim cleanup needed. */ 65 + exit(0); 74 66 } 75 67 76 68 void system_reboot(void) 77 69 { 78 - sim_thread_exception_wait(); 70 + /* "Reboot" on Android = exit; JS layer calls rb_daemon_start to come back. */ 71 + power_off(); 79 72 } 80 73 81 74 void system_exception_wait(void) 82 75 { 76 + /* Block the calling thread until quitting is set. Used by the engine 77 + * after a fatal panicf() so we don't spin on the dead path. */ 83 78 pthread_mutex_lock(&shutdown_lock); 84 79 while (!quitting) 85 80 pthread_cond_wait(&shutdown_cv, &shutdown_lock);
+4
lib/rbcodec/codecs/SOURCES
··· 42 42 sgc.c 43 43 vgm.c 44 44 #if MEMORYSIZE > 2 45 + /* SID needs cRSID, which uses GCC nested-functions and won't compile under 46 + * NDK clang. Skip on the Android cdylib build. */ 47 + #ifndef CODECS_STATIC 45 48 sid.c 49 + #endif 46 50 kss.c 47 51 #endif 48 52 aac_bsf.c
+5
lib/rbcodec/codecs/codecs.make
··· 84 84 include $(RBCODECLIB_DIR)/codecs/libgme/libemu2413.make 85 85 include $(RBCODECLIB_DIR)/codecs/libopus/libopus.make 86 86 ifneq ($(MEMORYSIZE),2) 87 + # cRSID (Commodore 64 SID format) uses GCC nested-function syntax that 88 + # NDK clang rejects strictly. Skip on the Android cdylib build; the .sid 89 + # format is niche and can be re-enabled later if demand surfaces. 90 + ifndef CODECS_STATIC 87 91 include $(RBCODECLIB_DIR)/codecs/cRSID/cRSID.make 92 + endif 88 93 endif 89 94 90 95 ifeq ($(shell expr $(GCCNUM) \> 600),1)
+3
tools/configure
··· 741 741 gcctarget="${cc_triple}-" 742 742 743 743 extradefines="$extradefines -DCODECS_STATIC -DZIG_APP -D__ANDROID__" 744 + # NDK r27 bionic's siginfo.h declares sigevent_t natively, so no shim 745 + # needed. (Earlier NDKs without it would need a typedef shim — added 746 + # only if a real build flags it as missing.) 744 747 export CODECS_STATIC=1 745 748 746 749 PATH="$ndk_toolchain/bin:$PATH"