actual featured page
This commit is contained in:
@@ -2,57 +2,85 @@
|
||||
* Smoke test: load libcavacore.dylib via bun:ffi, init → execute → destroy.
|
||||
* Run: bun tests/cavacore-smoke.ts
|
||||
*/
|
||||
import { dlopen, FFIType, ptr } from "bun:ffi"
|
||||
import { join } from "path"
|
||||
import { dlopen, FFIType, ptr } from "bun:ffi";
|
||||
import { join } from "path";
|
||||
|
||||
const libPath = join(import.meta.dir, "..", "src", "native", "libcavacore.dylib")
|
||||
const libPath = join(
|
||||
import.meta.dir,
|
||||
"..",
|
||||
"src",
|
||||
"native",
|
||||
"libcavacore.dylib",
|
||||
);
|
||||
|
||||
const lib = dlopen(libPath, {
|
||||
cava_init: {
|
||||
args: [FFIType.i32, FFIType.u32, FFIType.i32, FFIType.i32, FFIType.double, FFIType.i32, FFIType.i32],
|
||||
returns: FFIType.ptr,
|
||||
},
|
||||
cava_execute: {
|
||||
args: [FFIType.ptr, FFIType.i32, FFIType.ptr, FFIType.ptr],
|
||||
returns: FFIType.void,
|
||||
},
|
||||
cava_destroy: {
|
||||
args: [FFIType.ptr],
|
||||
returns: FFIType.void,
|
||||
},
|
||||
})
|
||||
cava_init: {
|
||||
args: [
|
||||
FFIType.i32,
|
||||
FFIType.u32,
|
||||
FFIType.i32,
|
||||
FFIType.i32,
|
||||
FFIType.double,
|
||||
FFIType.i32,
|
||||
FFIType.i32,
|
||||
FFIType.i32,
|
||||
],
|
||||
returns: FFIType.ptr,
|
||||
},
|
||||
cava_execute: {
|
||||
args: [FFIType.ptr, FFIType.i32, FFIType.ptr, FFIType.ptr],
|
||||
returns: FFIType.void,
|
||||
},
|
||||
cava_destroy: {
|
||||
args: [FFIType.ptr],
|
||||
returns: FFIType.void,
|
||||
},
|
||||
});
|
||||
|
||||
const bars = 10
|
||||
const rate = 44100
|
||||
const channels = 1
|
||||
const bars = 10;
|
||||
const rate = 44100;
|
||||
const channels = 1;
|
||||
|
||||
// Init
|
||||
const plan = lib.symbols.cava_init(bars, rate, channels, 1, 0.77, 50, 10000)
|
||||
const plan = lib.symbols.cava_init(
|
||||
bars,
|
||||
rate,
|
||||
channels,
|
||||
1,
|
||||
0.77,
|
||||
50,
|
||||
10000,
|
||||
0 /* CAVA_SCALING_LINEAR */,
|
||||
);
|
||||
if (!plan) {
|
||||
console.error("FAIL: cava_init returned null")
|
||||
process.exit(1)
|
||||
console.error("FAIL: cava_init returned null");
|
||||
process.exit(1);
|
||||
}
|
||||
console.log("cava_init OK, plan pointer:", plan)
|
||||
console.log("cava_init OK, plan pointer:", plan);
|
||||
|
||||
// Generate a 200Hz sine wave test signal
|
||||
const bufferSize = 512
|
||||
const cavaIn = new Float64Array(bufferSize)
|
||||
const cavaOut = new Float64Array(bars * channels)
|
||||
const bufferSize = 512;
|
||||
const cavaIn = new Float64Array(bufferSize);
|
||||
const cavaOut = new Float64Array(bars * channels);
|
||||
|
||||
for (let k = 0; k < 100; k++) {
|
||||
for (let n = 0; n < bufferSize; n++) {
|
||||
cavaIn[n] = Math.sin(2 * Math.PI * 200 / rate * (n + k * bufferSize)) * 20000
|
||||
}
|
||||
lib.symbols.cava_execute(ptr(cavaIn), bufferSize, ptr(cavaOut), plan)
|
||||
for (let n = 0; n < bufferSize; n++) {
|
||||
cavaIn[n] =
|
||||
Math.sin(((2 * Math.PI * 200) / rate) * (n + k * bufferSize)) * 20000;
|
||||
}
|
||||
lib.symbols.cava_execute(ptr(cavaIn), bufferSize, ptr(cavaOut), plan);
|
||||
}
|
||||
|
||||
console.log("cava_execute OK, output:", Array.from(cavaOut).map(v => v.toFixed(3)))
|
||||
console.log(
|
||||
"cava_execute OK, output:",
|
||||
Array.from(cavaOut).map((v) => v.toFixed(3)),
|
||||
);
|
||||
|
||||
// Check that bar 2 (200Hz) has the peak
|
||||
const maxIdx = cavaOut.indexOf(Math.max(...cavaOut))
|
||||
console.log(`Peak at bar ${maxIdx} (expected ~2 for 200Hz)`)
|
||||
const maxIdx = cavaOut.indexOf(Math.max(...cavaOut));
|
||||
console.log(`Peak at bar ${maxIdx} (expected ~2 for 200Hz)`);
|
||||
|
||||
// Destroy
|
||||
lib.symbols.cava_destroy(plan)
|
||||
console.log("cava_destroy OK")
|
||||
console.log("\nSMOKE TEST PASSED")
|
||||
lib.symbols.cava_destroy(plan);
|
||||
console.log("cava_destroy OK");
|
||||
console.log("\nSMOKE TEST PASSED");
|
||||
|
||||
Reference in New Issue
Block a user