A modern, network-enabled music player platform built on Rockbox technology. rockboxd.tsiry-sandratraina.com
rust deno navidrome airplay libadwaita zig mpris snapcast mpd rockbox audio subsonic
2

Configure Feed

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

chore(bindings/clojure): bump to 0.1.2; fix stale require in README

Bump the default VERSION to 0.1.2. Also correct the usage example's requires
to the rockbox.ffi.* namespaces (they were still showing the pre-rename
rockbox.metadata/dsp/player).

+25 -19
+6 -6
bindings/clojure/README.md
··· 37 37 ## Usage 38 38 39 39 ```clojure 40 - (require '[rockbox.metadata :as metadata] 41 - '[rockbox.dsp :as dsp] 42 - '[rockbox.player :as player]) 40 + (require '[rockbox.ffi.metadata :as metadata] 41 + '[rockbox.ffi.dsp :as dsp] 42 + '[rockbox.ffi.player :as player]) 43 43 44 44 ;; metadata -> map with keyword keys 45 45 (metadata/read "/music/song.flac") ; => {:title "…" :codec "FLAC" …} ··· 90 90 # 1. stage the prebuilt libs for every platform into the jar resources 91 91 bindings/scripts/fetch-libs.sh --all 92 92 93 - # 2. one-shot release: stamp cljdoc config, commit + tag clojure-ffi-v0.1.1, 93 + # 2. one-shot release: stamp cljdoc config, commit + tag clojure-ffi-v0.1.2, 94 94 # deploy to Clojars, push the tag, and request a cljdoc build 95 - VERSION=0.1.1 CLOJARS_USERNAME=tsirysndr CLOJARS_PASSWORD=<deploy-token> \ 95 + VERSION=0.1.2 CLOJARS_USERNAME=tsirysndr CLOJARS_PASSWORD=<deploy-token> \ 96 96 mise exec -- clojure -T:build release 97 97 ``` 98 98 ··· 103 103 sources — `release` creates and pushes it. Consume it with: 104 104 105 105 ```clojure 106 - io.github.tsirysndr/rockbox-ffi {:mvn/version "0.1.1"} 106 + io.github.tsirysndr/rockbox-ffi {:mvn/version "0.1.2"} 107 107 ``` 108 108 109 109 ### Coexisting with the `rockbox-clj` SDK
+3 -3
bindings/clojure/build.clj
··· 19 19 20 20 Usage: 21 21 clojure -T:build jar 22 - VERSION=0.1.1 clojure -T:build install # -> local ~/.m2 23 - VERSION=0.1.1 CLOJARS_USERNAME=<user> CLOJARS_PASSWORD=<token> \\ 22 + VERSION=0.1.2 clojure -T:build install # -> local ~/.m2 23 + VERSION=0.1.2 CLOJARS_USERNAME=<user> CLOJARS_PASSWORD=<token> \\ 24 24 clojure -T:build release # stamp+tag+deploy+cljdoc 25 25 Lower-level: `stamp-cljdoc`, `deploy` (Clojars only), `request-cljdoc`." 26 26 (:require [clojure.tools.build.api :as b] ··· 28 28 [deps-deploy.deps-deploy :as dd])) 29 29 30 30 (def lib 'io.github.tsirysndr/rockbox-ffi) 31 - (def version (or (System/getenv "VERSION") "0.1.1")) 31 + (def version (or (System/getenv "VERSION") "0.1.2")) 32 32 (def tag (str "clojure-ffi-v" version)) 33 33 (def class-dir "target/classes") 34 34 (def basis (delay (b/create-basis {:project "deps.edn"})))
+14 -8
bindings/clojure/src/rockbox/ffi.clj
··· 77 77 "rockbox-ffi`. Tried:\n " (str/join "\n " tried)) 78 78 {:tried (vec tried)}))))) 79 79 80 - (def ^:private linker (Linker/nativeLinker)) 80 + ;; Lazy: even Linker/nativeLinker is a Foreign-API call, kept out of ns load so 81 + ;; requiring this namespace does no FFM work (cljdoc analysis, older JDKs). 82 + (def ^:private linker (delay (Linker/nativeLinker))) 81 83 82 84 ;; The library outlives every call, so it lives in the global arena (never 83 - ;; unloaded). The lookup is created once, process-wide. 84 - (def ^:private lookup (SymbolLookup/libraryLookup (locate-lib) (Arena/global))) 85 + ;; unloaded). Loaded lazily on first FFI use — merely `require`-ing this 86 + ;; namespace (e.g. for cljdoc doc analysis) must NOT touch native code. 87 + (def ^:private lookup (delay (SymbolLookup/libraryLookup (locate-lib) (Arena/global)))) 85 88 86 89 (defn- fd-of ^FunctionDescriptor [ret args] 87 90 (FunctionDescriptor/of ret (into-array MemoryLayout args))) ··· 90 93 (FunctionDescriptor/ofVoid (into-array MemoryLayout args))) 91 94 92 95 (defn- dc ^MethodHandle [^String name ^FunctionDescriptor fd] 93 - (let [sym (-> lookup (.find name) 96 + (let [sym (-> @lookup (.find name) 94 97 (.orElseThrow (reify java.util.function.Supplier 95 98 (get [_] (ex-info (str "symbol " name " not found in librockbox_ffi") {})))))] 96 - (.downcallHandle linker sym fd (make-array Linker$Option 0)))) 99 + (.downcallHandle @linker sym fd (make-array Linker$Option 0)))) 97 100 101 + ;; Bound lazily (a delay): the downcall handles are built on first FFI call, 102 + ;; not at namespace load, so requiring this ns never dlopens the library. 98 103 (def ^:private handles 99 - {;; ---- deallocators / version ---- 104 + (delay 105 + {;; ---- deallocators / version ---- 100 106 :abi-version (dc "rb_ffi_abi_version" (fd-of I32 [])) 101 107 :string-free (dc "rb_string_free" (fd-void [PTR])) 102 108 :buffer-free (dc "rb_buffer_free" (fd-void [PTR I64])) ··· 141 147 :player-set-replaygain (dc "rb_player_set_replaygain" (fd-void [PTR I32 F32 BOOL])) 142 148 :player-volume (dc "rb_player_volume" (fd-of F32 [PTR])) 143 149 :player-sample-rate (dc "rb_player_sample_rate" (fd-of I32 [PTR])) 144 - :player-status-json (dc "rb_player_status_json" (fd-of PTR [PTR]))}) 150 + :player-status-json (dc "rb_player_status_json" (fd-of PTR [PTR]))})) 145 151 146 152 (defn call 147 153 "Invoke the C function bound to `k`. Args must already be the right JVM type 148 154 (use int/long/float/boolean/MemorySegment at the call site — the ABI does no 149 155 narrowing). Returns the boxed result, or nil for void functions." 150 156 [k & args] 151 - (.invokeWithArguments ^MethodHandle (get handles k) (to-array args))) 157 + (.invokeWithArguments ^MethodHandle (get @handles k) (to-array args))) 152 158 153 159 (defn take-string 154 160 "Copy a heap C string returned by the ABI into a String, then free it.
+2 -2
doc/cljdoc.edn
··· 1 1 {:cljdoc.doc/tree 2 - [["Readme" {:file "sdk/clojure/README.md"}] 3 - ["Examples" {:file "sdk/clojure/examples/README.md"}]]} 2 + [["Readme" {:file "bindings/clojure/README.md"}] 3 + ["Examples" {:file "bindings/clojure/examples/README.md"}]]}