Skip to content

Commit

Permalink
Merge pull request #146 from ircam-ismm/refactor/rs-utils
Browse files Browse the repository at this point in the history
refactor: get rid of to_byte_slice and get_symbol_for utils, fix #125
  • Loading branch information
b-ma authored Jan 7, 2025
2 parents cacb4ea + 7b86907 commit c7bc7c3
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 46 deletions.
27 changes: 15 additions & 12 deletions generator/rs/audio_nodes.tmpl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ fn listen_to_ended_event(
use napi::threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode};
use web_audio_api::Event;

let k_onended = crate::utils::get_symbol_for(env, "node-web-audio-api:onended");
let k_onended = env.symbol_for("node-web-audio-api:onended")?;
let ended_cb = js_this.get_property(k_onended).unwrap();
let mut ended_tsfn = env.create_threadsafe_function(
&ended_cb,
Expand Down Expand Up @@ -536,17 +536,20 @@ fn get_${d.slug(attr)}(ctx: CallContext) -> Result<JsUnknown> {

if let Some(arr_f32) = value {
let length = arr_f32.len();
let arr_u8 = crate::utils::to_byte_slice(arr_f32);

Ok(ctx.env
.create_arraybuffer_with_data(arr_u8.to_vec())
.map(|array_buffer| {
array_buffer
.into_raw()
.into_typedarray(TypedArrayType::Float32, length, 0)
})
.unwrap()?
.into_unknown())

let array_buffer = ctx.env.create_arraybuffer(length * 4).unwrap();
let js_typed_array = array_buffer
.into_raw()
.into_typedarray(TypedArrayType::Float32, length, 0)?;

let mut js_typed_array_value = js_typed_array.into_value()?;
let buffer: &mut [f32] = js_typed_array_value.as_mut();
buffer.copy_from_slice(arr_f32);

let js_typed_array = js_typed_array_value.arraybuffer
.into_typedarray(TypedArrayType::Float32, length, 0)?;

Ok(js_typed_array.into_unknown())
} else {
Ok(ctx.env.get_null()?.into_unknown())
}
Expand Down
2 changes: 1 addition & 1 deletion src/audio_buffer_source_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ fn listen_to_ended_event(
use napi::threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode};
use web_audio_api::Event;

let k_onended = crate::utils::get_symbol_for(env, "node-web-audio-api:onended");
let k_onended = env.symbol_for("node-web-audio-api:onended")?;
let ended_cb = js_this.get_property(k_onended).unwrap();
let mut ended_tsfn =
env.create_threadsafe_function(&ended_cb, 0, |ctx: ThreadSafeCallContext<Event>| {
Expand Down
4 changes: 2 additions & 2 deletions src/audio_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ fn listen_to_events(ctx: CallContext) -> Result<JsUndefined> {
let napi_context = ctx.env.unwrap::<NapiAudioContext>(&js_this)?;
let context = napi_context.unwrap();

let k_onsinkchange = crate::utils::get_symbol_for(ctx.env, "node-web-audio-api:onsinkchange");
let k_onsinkchange = ctx.env.symbol_for("node-web-audio-api:onsinkchange")?;
let sinkchange_cb = js_this.get_property(k_onsinkchange).unwrap();
let mut sinkchange_tsfn = ctx.env.create_threadsafe_function(
&sinkchange_cb,
Expand All @@ -250,7 +250,7 @@ fn listen_to_events(ctx: CallContext) -> Result<JsUndefined> {
},
)?;

let k_onstatechange = crate::utils::get_symbol_for(ctx.env, "node-web-audio-api:onstatechange");
let k_onstatechange = ctx.env.symbol_for("node-web-audio-api:onstatechange")?;
let statechange_cb = js_this.get_property(k_onstatechange).unwrap();
let context_clone = Arc::clone(&napi_context.0);

Expand Down
2 changes: 1 addition & 1 deletion src/audio_render_capacity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ fn listen_to_events(ctx: CallContext) -> Result<JsUndefined> {
let napi_node = ctx.env.unwrap::<NapiAudioRenderCapacity>(&js_this)?;
let node = napi_node.unwrap();

let k_onupdate = crate::utils::get_symbol_for(ctx.env, "node-web-audio-api:onupdate");
let k_onupdate = ctx.env.symbol_for("node-web-audio-api:onupdate")?;
let update_cb = js_this.get_property(k_onupdate).unwrap();
let mut update_tsfn = ctx.env.create_threadsafe_function(
&update_cb,
Expand Down
2 changes: 1 addition & 1 deletion src/constant_source_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ fn listen_to_ended_event(
use napi::threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode};
use web_audio_api::Event;

let k_onended = crate::utils::get_symbol_for(env, "node-web-audio-api:onended");
let k_onended = env.symbol_for("node-web-audio-api:onended")?;
let ended_cb = js_this.get_property(k_onended).unwrap();
let mut ended_tsfn =
env.create_threadsafe_function(&ended_cb, 0, |ctx: ThreadSafeCallContext<Event>| {
Expand Down
4 changes: 2 additions & 2 deletions src/offline_audio_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn start_rendering(ctx: CallContext) -> Result<JsObject> {
let napi_context = ctx.env.unwrap::<NapiOfflineAudioContext>(&js_this)?;
let context = napi_context.unwrap();

let k_onstatechange = crate::utils::get_symbol_for(ctx.env, "node-web-audio-api:onstatechange");
let k_onstatechange = ctx.env.symbol_for("node-web-audio-api:onstatechange")?;
let statechange_cb = js_this.get_property(k_onstatechange).unwrap();
let mut statechange_tsfn = ctx.env.create_threadsafe_function(
&statechange_cb,
Expand All @@ -122,7 +122,7 @@ fn start_rendering(ctx: CallContext) -> Result<JsObject> {
statechange_tsfn.call(Ok(e), ThreadsafeFunctionCallMode::Blocking);
});

let k_oncomplete = crate::utils::get_symbol_for(ctx.env, "node-web-audio-api:oncomplete");
let k_oncomplete = ctx.env.symbol_for("node-web-audio-api:oncomplete")?;
let complete_cb = js_this.get_property(k_oncomplete).unwrap();
let context_clone = Arc::clone(&napi_context.0);

Expand Down
2 changes: 1 addition & 1 deletion src/oscillator_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ fn listen_to_ended_event(env: &Env, js_this: &JsObject, node: &mut OscillatorNod
use napi::threadsafe_function::{ThreadSafeCallContext, ThreadsafeFunctionCallMode};
use web_audio_api::Event;

let k_onended = crate::utils::get_symbol_for(env, "node-web-audio-api:onended");
let k_onended = env.symbol_for("node-web-audio-api:onended")?;
let ended_cb = js_this.get_property(k_onended).unwrap();
let mut ended_tsfn =
env.create_threadsafe_function(&ended_cb, 0, |ctx: ThreadSafeCallContext<Event>| {
Expand Down
3 changes: 1 addition & 2 deletions src/script_processor_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,7 @@ fn listen_to_events(ctx: CallContext) -> Result<JsUndefined> {
let napi_node = ctx.env.unwrap::<NapiScriptProcessorNode>(&js_this)?;
let node = napi_node.unwrap();

let k_onaudioprocess =
crate::utils::get_symbol_for(ctx.env, "node-web-audio-api:onaudioprocess");
let k_onaudioprocess = ctx.env.symbol_for("node-web-audio-api:onaudioprocess")?;
let audioprocess_cb: JsFunction = js_this.get_property(k_onaudioprocess).unwrap();

let audioprocess_tsfn = ThreadsafeFunctionPatched::create(
Expand Down
14 changes: 2 additions & 12 deletions src/utils/mod.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,10 @@
use napi::{Env, JsFunction, JsObject, JsSymbol, Result};
use napi::{Env, JsFunction, JsObject, Result};

// alternative implementation of Napi ThreadsafeFunction
// cf. // cf. https://github.com/parcel-bundler/lightningcss/blob/master/napi/src/threadsafe_function.rs
// cf. https://github.com/parcel-bundler/lightningcss/blob/master/napi/src/threadsafe_function.rs
mod thread_safe_function;
pub(crate) use thread_safe_function::*;

// cf. https://users.rust-lang.org/t/vec-f32-to-u8/21522/7
#[allow(clippy::needless_lifetimes)]
pub(crate) fn to_byte_slice<'a>(floats: &'a [f32]) -> &'a [u8] {
unsafe { std::slice::from_raw_parts(floats.as_ptr() as *const _, floats.len() * 4) }
}

pub(crate) fn get_symbol_for(env: &Env, name: &str) -> JsSymbol {
env.symbol_for(name).unwrap()
}

pub(crate) fn get_class_ctor(env: &Env, name: &str) -> Result<JsFunction> {
let store_ref: &mut napi::Ref<()> = env.get_instance_data()?.unwrap();
let store: JsObject = env.get_reference_value(store_ref)?;
Expand Down
29 changes: 17 additions & 12 deletions src/wave_shaper_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,23 @@ fn get_curve(ctx: CallContext) -> Result<JsUnknown> {

if let Some(arr_f32) = value {
let length = arr_f32.len();
let arr_u8 = crate::utils::to_byte_slice(arr_f32);

Ok(ctx
.env
.create_arraybuffer_with_data(arr_u8.to_vec())
.map(|array_buffer| {
array_buffer
.into_raw()
.into_typedarray(TypedArrayType::Float32, length, 0)
})
.unwrap()?
.into_unknown())

let array_buffer = ctx.env.create_arraybuffer(length * 4).unwrap();
let js_typed_array =
array_buffer
.into_raw()
.into_typedarray(TypedArrayType::Float32, length, 0)?;

let mut js_typed_array_value = js_typed_array.into_value()?;
let buffer: &mut [f32] = js_typed_array_value.as_mut();
buffer.copy_from_slice(arr_f32);

let js_typed_array =
js_typed_array_value
.arraybuffer
.into_typedarray(TypedArrayType::Float32, length, 0)?;

Ok(js_typed_array.into_unknown())
} else {
Ok(ctx.env.get_null()?.into_unknown())
}
Expand Down
21 changes: 21 additions & 0 deletions tests/WaveShaper.spec.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { assert } from 'chai';
import { AudioContext } from '../index.mjs';

describe('# WaveShaper', () => {
describe('## curve', () => {
it('getter should return a copy of the given curve', async () => {
const context = new AudioContext({});
const curve = new Float32Array([-1, -0.5, 0, 0.5, 1]);

const ws = context.createWaveShaper();
ws.curve = curve;

// same content
assert.deepEqual(curve, ws.curve);
// not the same instance
assert.notStrictEqual(curve, ws.curve);

await context.close();
});
});
});

0 comments on commit c7bc7c3

Please sign in to comment.