m3, ui/ux, and more

This commit is contained in:
Boof2015
2026-06-17 16:12:51 -04:00
parent 0afbb37c08
commit 9f2ce3bb75
533 changed files with 5933 additions and 147 deletions
@@ -0,0 +1,2 @@
<manifest>
</manifest>
@@ -0,0 +1,28 @@
package expo.modules.astrascope
import expo.modules.kotlin.modules.Module
import expo.modules.kotlin.modules.ModuleDefinition
import expo.modules.kotlin.typedarray.Float32Array
/**
* JS surface for the realtime scope. Both functions are synchronous (JSI):
* [getSpectrumFrame] is pulled once per render frame from the JS thread and
* fills a JS-preallocated Float32Array in place (no per-frame allocation, no
* event-emitter traffic). The PCM that feeds it arrives on the audio thread via
* the vendored kotlin-audio tap -> [ScopeBridge].
*/
class AstraScopeModule : Module() {
override fun definition() = ModuleDefinition {
Name("AstraScope")
// Gate the audio-thread tap (off when backgrounded/paused/reduced-motion).
Function("setActive") { active: Boolean ->
ScopeBridge.active = active
}
// Fill `out` with the latest dB spectrum; returns the number of bins written.
Function("getSpectrumFrame") { out: Float32Array ->
ScopeBridge.nativeFillSpectrum(out.toDirectBuffer(), out.length)
}
}
}
@@ -0,0 +1,36 @@
package expo.modules.astrascope
/**
* Process-wide bridge to the native scope driver (libastrascope.so).
*
* Loaded once here; the vendored kotlin-audio PCM tap (ScopeTapAudioProcessor)
* calls [nativePushFrames]/[nativeConfigure] from the ExoPlayer audio thread,
* while [AstraScopeModule] calls [nativeFillSpectrum] from the JS thread. The
* native side is single-producer/single-consumer and lock-free on the audio
* path; see scope_ring.h.
*
* [active] gates the tap so a backgrounded/paused app pays ~zero in the audio
* callback. The lifecycle owner (RN side) flips it via AstraScope.setActive().
*/
object ScopeBridge {
init {
System.loadLibrary("astrascope")
}
/** Set by the lifecycle owner; checked cheaply in the audio callback. */
@Volatile
var active: Boolean = false
/** Audio thread. Tell the analyzer the stream's sample rate / channels. */
external fun nativeConfigure(sampleRate: Int, channelCount: Int)
/** Audio thread. Push interleaved float PCM (frameCount * channelCount). */
external fun nativePushFrames(frames: FloatArray, frameCount: Int, channelCount: Int)
/**
* Render thread. Fill `buffer` (a direct ByteBuffer over the JS Float32Array's
* memory) with the latest dB spectrum, up to `capacityFloats` floats.
* Returns the number of bins written. Zero-copy: writes straight into JS memory.
*/
external fun nativeFillSpectrum(buffer: java.nio.ByteBuffer, capacityFloats: Int): Int
}