mirror of
https://github.com/Boof2015/astra-mobile.git
synced 2026-08-16 08:10:43 +02:00
m3, ui/ux, and more
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(astrascope)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Pure portable DSP + a plain-JNI bridge. No prefab / ReactAndroid / fbjni:
|
||||
# <jni.h> comes from the NDK sysroot and we only link liblog.
|
||||
add_library(astrascope SHARED
|
||||
../cpp/dsp_utils.cpp
|
||||
../cpp/spectrum.cpp
|
||||
../cpp/oscilloscope.cpp
|
||||
../cpp/vectorscope.cpp
|
||||
../cpp/scope_jni.cpp)
|
||||
|
||||
target_include_directories(astrascope PRIVATE ../cpp)
|
||||
|
||||
find_library(log-lib log)
|
||||
target_link_libraries(astrascope ${log-lib})
|
||||
@@ -0,0 +1,35 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'expo-module-gradle-plugin'
|
||||
}
|
||||
|
||||
group = 'expo.modules.astrascope'
|
||||
version = '0.1.0'
|
||||
|
||||
def reactNativeArchitectures() {
|
||||
def value = project.getProperties().get("reactNativeArchitectures")
|
||||
return value ? value.split(",") : ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]
|
||||
}
|
||||
|
||||
android {
|
||||
namespace "expo.modules.astrascope"
|
||||
defaultConfig {
|
||||
versionCode 1
|
||||
versionName "0.1.0"
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags "-O3 -std=c++17 -fexceptions -frtti"
|
||||
abiFilters(*reactNativeArchitectures())
|
||||
arguments "-DANDROID_STL=c++_shared"
|
||||
}
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user