adjust smoothing in now playing spectrum

This commit is contained in:
Boof2015
2026-07-15 14:50:56 -04:00
parent b290cfed7a
commit b5f1ca9e99
9 changed files with 55 additions and 19 deletions
@@ -21,8 +21,8 @@ class AstraScopeModule : Module() {
}
// Fill `out` with the latest dB spectrum; returns the number of bins written.
Function("getSpectrumFrame") { out: Float32Array ->
ScopeBridge.nativeFillSpectrum(out.toDirectBuffer(), out.length)
Function("getSpectrumFrame") { out: Float32Array, smoothing: Double ->
ScopeBridge.nativeFillSpectrum(out.toDirectBuffer(), out.length, smoothing.toFloat())
}
// Fill `out` with render-ready oscilloscope points (~[-1,1]).
@@ -36,8 +36,8 @@ class AstraScopeModule : Module() {
ScopeBridge.postEqActive = active
}
Function("getSpectrumFramePostEq") { out: Float32Array ->
ScopeBridge.nativeFillSpectrumPostEq(out.toDirectBuffer(), out.length)
Function("getSpectrumFramePostEq") { out: Float32Array, smoothing: Double ->
ScopeBridge.nativeFillSpectrumPostEq(out.toDirectBuffer(), out.length, smoothing.toFloat())
}
// --- M4: EQ params + per-track gain (consumed by the kotlin-audio processors) ---
@@ -40,7 +40,11 @@ object ScopeBridge {
* 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
external fun nativeFillSpectrum(
buffer: java.nio.ByteBuffer,
capacityFloats: Int,
smoothing: Float
): Int
/**
* Render thread. Fill `buffer` (a direct ByteBuffer over the JS Float32Array's
@@ -57,5 +61,9 @@ object ScopeBridge {
* Render thread. Fill `buffer` with the latest POST-EQ dB spectrum (feeds the
* EQ screen's response-curve overlay). Returns bins written. Zero-copy.
*/
external fun nativeFillSpectrumPostEq(buffer: java.nio.ByteBuffer, capacityFloats: Int): Int
external fun nativeFillSpectrumPostEq(
buffer: java.nio.ByteBuffer,
capacityFloats: Int,
smoothing: Float
): Int
}
+8 -4
View File
@@ -45,7 +45,8 @@ Java_expo_modules_astrascope_ScopeBridge_nativePushFrames(
// Zero-copy: writes straight into the JS-owned ArrayBuffer.
JNIEXPORT jint JNICALL
Java_expo_modules_astrascope_ScopeBridge_nativeFillSpectrum(
JNIEnv* env, jobject /*thiz*/, jobject buffer, jint capacityFloats) {
JNIEnv* env, jobject /*thiz*/, jobject buffer, jint capacityFloats,
jfloat smoothing) {
if (buffer == nullptr || capacityFloats <= 0) {
return 0;
}
@@ -53,7 +54,8 @@ Java_expo_modules_astrascope_ScopeBridge_nativeFillSpectrum(
if (dst == nullptr) {
return 0;
}
const size_t n = driver().fillSpectrum(dst, static_cast<size_t>(capacityFloats));
const size_t n = driver().fillSpectrum(
dst, static_cast<size_t>(capacityFloats), static_cast<float>(smoothing));
return static_cast<jint>(n);
}
@@ -95,7 +97,8 @@ Java_expo_modules_astrascope_ScopeBridge_nativePushFramesPostEq(
JNIEXPORT jint JNICALL
Java_expo_modules_astrascope_ScopeBridge_nativeFillSpectrumPostEq(
JNIEnv* env, jobject /*thiz*/, jobject buffer, jint capacityFloats) {
JNIEnv* env, jobject /*thiz*/, jobject buffer, jint capacityFloats,
jfloat smoothing) {
if (buffer == nullptr || capacityFloats <= 0) {
return 0;
}
@@ -103,7 +106,8 @@ Java_expo_modules_astrascope_ScopeBridge_nativeFillSpectrumPostEq(
if (dst == nullptr) {
return 0;
}
const size_t n = driver().fillSpectrumPostEq(dst, static_cast<size_t>(capacityFloats));
const size_t n = driver().fillSpectrumPostEq(
dst, static_cast<size_t>(capacityFloats), static_cast<float>(smoothing));
return static_cast<jint>(n);
}
+6 -2
View File
@@ -68,11 +68,13 @@ class ScopeDriver {
// Render thread (single consumer). Snapshot the most recent fftSize mono
// samples, run the FFT, copy up to `cap` dB magnitudes into `out`.
// Returns the number of bins written.
size_t fillSpectrum(float* out, size_t cap) {
size_t fillSpectrum(float* out, size_t cap, float smoothing) {
if (out == nullptr || cap == 0) {
return 0;
}
spectrum_.setSmoothing(smoothing);
const int sr = pendingSampleRate_.load(std::memory_order_acquire);
if (sr != appliedSampleRate_) {
spectrum_.setSampleRate(static_cast<float>(sr));
@@ -209,11 +211,13 @@ class ScopeDriver {
}
// Render thread. Latest post-EQ spectrum window -> `out` (dB magnitudes).
size_t fillSpectrumPostEq(float* out, size_t cap) {
size_t fillSpectrumPostEq(float* out, size_t cap, float smoothing) {
if (out == nullptr || cap == 0) {
return 0;
}
postEqSpectrum_.setSmoothing(smoothing);
const int sr = pendingSampleRate_.load(std::memory_order_acquire);
if (sr != postEqAppliedSampleRate_) {
postEqSpectrum_.setSampleRate(static_cast<float>(sr));
+5 -4
View File
@@ -15,10 +15,11 @@ declare class AstraScopeModuleType extends NativeModule {
setActive(active: boolean): void;
/**
* Fill `out` (length should be {@link SPECTRUM_BINS}) with the latest dB
* spectrum magnitudes in place; returns the number of bins written. Call once
* per render frame from the JS thread.
* spectrum magnitudes in place; returns the number of bins written. `smoothing`
* is the previous-frame retention in [0, 0.99]. Call once per render frame
* from the JS thread.
*/
getSpectrumFrame(out: Float32Array): number;
getSpectrumFrame(out: Float32Array, smoothing: number): number;
/**
* Fill `out` with render-ready, evenly spaced points from the latest
* pitch-locked oscilloscope window. Values are interpolated visual samples in
@@ -31,7 +32,7 @@ declare class AstraScopeModuleType extends NativeModule {
* Like {@link getSpectrumFrame} but for the POST-EQ tap (ring #2) — feeds the
* EQ screen's spectrum behind the response curve. Returns bins written.
*/
getSpectrumFramePostEq(out: Float32Array): number;
getSpectrumFramePostEq(out: Float32Array, smoothing: number): number;
// --- M4 EQ + per-track gain (params pushed from JS; biquad coeffs computed
// natively at the real stream sample rate) ---