A disclaimer: I am a total noob on Rust. I thought that the best way for me to get into it, is to integrate into a project of my own.
I do not know how to debug this. The rust code compiles. I get a runtime "Attempt to use a moved value" on the web browser's console.log. I suppose I am misusing ownership somehow from JS.
I created a stripped down version of the project just to demonstrate this error in context, if anyone wants to see:
github /autotel/rust-audio-in-browser-minimum
(sorry, the forum wouldn't let me post more than 2 links)
These are the lines where I expect the mistake to be:
Lib.rs:
The structs that are compiled with emscripten and instanced in a web audio worklet.
context: rust-audio-in-browser-minimum/lib.rs at main · autotel/rust-audio-in-browser-minimum · GitHub
#[wasm_bindgen]
pub struct PolyManager {
max_voices: usize,
last_stolen_voice: usize,
}
#[wasm_bindgen]
impl PolyManager {
pub fn new() -> PolyManager {
log("Rust: new PolyManager");
utils::set_panic_hook();
let ret = PolyManager {
max_voices: 32,
last_stolen_voice: 0,
};
ret
}
pub fn trig(&mut self, freq: f32, amp: f32) {
// does a thing
}
pub fn get_dummy_block(self, block_size: usize) -> Vec<f32> {
let mut mix = Vec::new();
for sample_n in 0..block_size {
let f = 220.;
let sf = SAMPLING_RATE as f32 / f;
// let rand: f32 = rand::random(); // Also got problems with rand. Left that for later.
let rand: f32 = ((sample_n as f32 / sf) % 1.) - 0.5; // using sawtooth instead.
mix.push(rand);
}
mix
}
}
MagicEngineWorklet.js
the js worklet that invokes the rust module.
in context: rust-audio-in-browser-minimum/MagicEngine.js at main · autotel/rust-audio-in-browser-minimum · GitHub
class MagicWorklet extends AudioWorkletProcessor {
/** @type {PolyManager|null} */
rustSynthesizer = null;
/** @type {Object|null} */
webAssemblyInstance = null;
constructor() {
super();
console.log("magic-worklet instanced");
this.samples = [];
this.totalSamples = 0;
this.port.onmessage = ({ data: { type, data, wasmBytes } }) => {
if (halted) return console.log("halted");
const importObject = {
env: {},
};
// loading WASM into a worker is a huge PITA
// https://github.com/the-drunk-coder/ruffbox/blob/master/js/worklet.js
// https://steemit.com/eos/@skenan/eos-development-for-beginners-webassembly
// https://github.com/Ameobea/web-synth/blob/main/public/WaveTableNodeProcessor.js
if (type === "load-wasm") {
console.log("worklet: load-wasm received", wasmBytes);
init(WebAssembly.compile(wasmBytes)).then(() => {
console.log({ PolyManager });
this.rustSynthesizer = PolyManager.new();
// this.rustSynthesizer = new PolyManager();
console.log({rustSynthesizer:this.rustSynthesizer});
return this.port.postMessage({ type: "wasm-loaded" });
})
} else if (type == "trig") {
if (!this.rustSynthesizer) return console.log("not isntanced");
console.log("worklet:", data);
const freq = 55 * Math.pow(2, data.note / 12);
try {
this.rustSynthesizer.trig(freq, 1);
console.log("trigger succesful");
} catch (e) {
devRustErrorHandler();
console.error(e);
}
}
};
}
process(inputs, outputs, parameters) {
if (!this.rustSynthesizer) {
console.log("not ready");
return true;
}
const firstOutput = outputs[0];
/** @type {number} */
const blockSize = firstOutput[0].length;
try {
// const mix = this.rustSynthesizer.get_block(blockSize);
const mix = this.rustSynthesizer.get_dummy_block(blockSize);
firstOutput.forEach(
/**
* @param {Float32Array} channel
* @param {number} channelN
*/
(channel, channelN) => {
channel.set(mix)
}
)
} catch (e) {
console.log("audioblock worklet error", e);
}
return true;
}
}
registerProcessor("magic-worklet", MagicWorklet);
The error
sorry for naming the lib as rrr
audioblock worklet error Error: Attempt to use a moved value
at PolyManager.get_dummy_block (rrr.js:200:38)
at MagicWorklet.process (MagicEngineWorklet.js?t=1649581669029:88:46)
Many thanks!