Provide SignalProcessing methods to the Lua script
This is accomplished by providing a wrapped reference to the SignalProcessing instance of the Rust program as a global Lua variable. The wrapper class implements mlua::UserData, wraps the relevant SignalProcessing methods and provides them as Lua methods. So far, this is implemented for get_energy_in_band() only.
This commit is contained in:
parent
62bbff481c
commit
864add8403
39
src/main.rs
39
src/main.rs
|
@ -12,25 +12,29 @@ mod userscript;
|
|||
use crate::signal_processing::SignalProcessing;
|
||||
use crate::userscript::UserScript;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
fn main()
|
||||
{
|
||||
let mut stdin = std::io::stdin();
|
||||
|
||||
// set up Lua environment
|
||||
|
||||
println!("Loading user script...");
|
||||
|
||||
let script = UserScript::new("test.lua").unwrap();
|
||||
|
||||
println!("Calling init()...");
|
||||
|
||||
script.init().unwrap();
|
||||
|
||||
// set up signal processing
|
||||
|
||||
println!("Initializing signal processing...");
|
||||
|
||||
let mut sigproc = SignalProcessing::new(config::BLOCK_LEN, config::SAMP_RATE).unwrap();
|
||||
let sigproc = Rc::new(RefCell::new(
|
||||
SignalProcessing::new(config::BLOCK_LEN, config::SAMP_RATE).unwrap()));
|
||||
|
||||
// set up Lua environment
|
||||
|
||||
println!("Loading user script...");
|
||||
|
||||
let script = UserScript::new(sigproc.clone(), "test.lua").unwrap();
|
||||
|
||||
println!("Calling init()...");
|
||||
|
||||
script.init().unwrap();
|
||||
|
||||
println!("Done! Starting main loop…");
|
||||
|
||||
|
@ -67,12 +71,15 @@ fn main()
|
|||
}
|
||||
|
||||
|
||||
sigproc.import_i16_mono_from_iter(samples.iter()).unwrap();
|
||||
sigproc.update_fft().unwrap();
|
||||
{
|
||||
let mut s = sigproc.borrow_mut();
|
||||
s.import_i16_mono_from_iter(samples.iter()).unwrap();
|
||||
s.update_fft().unwrap();
|
||||
}
|
||||
|
||||
let energy_bass = sigproc.get_energy_in_band( 0.0, 400.0);
|
||||
let energy_mid = sigproc.get_energy_in_band( 400.0, 4000.0);
|
||||
let energy_treble = sigproc.get_energy_in_band(4000.0, config::SAMP_RATE/2.0);
|
||||
let energy_bass = sigproc.borrow().get_energy_in_band( 0.0, 400.0);
|
||||
let energy_mid = sigproc.borrow().get_energy_in_band( 400.0, 4000.0);
|
||||
let energy_treble = sigproc.borrow().get_energy_in_band(4000.0, config::SAMP_RATE/2.0);
|
||||
|
||||
// dump the output
|
||||
println!("Bass: {:11.2} – Mid: {:11.2} – Treble: {:11.2}", energy_bass, energy_mid, energy_treble);
|
||||
|
|
|
@ -21,11 +21,15 @@
|
|||
*/
|
||||
|
||||
use crate::config;
|
||||
use crate::signal_processing::SignalProcessing;
|
||||
|
||||
use mlua::Lua;
|
||||
use mlua::FromLua;
|
||||
use mlua::Error;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
pub struct UserScript
|
||||
{
|
||||
lua_state: Lua,
|
||||
|
@ -33,12 +37,26 @@ pub struct UserScript
|
|||
|
||||
impl UserScript
|
||||
{
|
||||
pub fn new(user_script_path: &str) -> std::result::Result<UserScript, mlua::Error>
|
||||
pub fn new(sigproc: Rc<RefCell<SignalProcessing>>, user_script_path: &str) -> std::result::Result<UserScript, mlua::Error>
|
||||
{
|
||||
let s = UserScript {
|
||||
lua_state: Lua::new(),
|
||||
};
|
||||
|
||||
// provide some configuration constants to Lua via a table
|
||||
let config_table = s.lua_state.create_table()?;
|
||||
|
||||
config_table.set("sampling_rate", config::SAMP_RATE)?;
|
||||
config_table.set("block_length", config::BLOCK_LEN)?;
|
||||
config_table.set("samples_per_update", config::SAMPLES_PER_UPDATE)?;
|
||||
|
||||
s.lua_state.globals().set("CONFIG", config_table)?;
|
||||
|
||||
// register the signal processing reference as Lua user data
|
||||
s.lua_state.globals().set("sigproc", SignalProcessingWrapper{
|
||||
signal_processing: sigproc
|
||||
})?;
|
||||
|
||||
// load the user script and execute it to make variables and functions available
|
||||
let user_script = std::fs::read_to_string(user_script_path)?;
|
||||
s.lua_state.load(&user_script).exec()?;
|
||||
|
@ -93,3 +111,23 @@ impl UserScript
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrap a SignalProcessing instance and provide a Lua interface for some of its methods.
|
||||
*/
|
||||
struct SignalProcessingWrapper
|
||||
{
|
||||
signal_processing: Rc<RefCell<SignalProcessing>>,
|
||||
}
|
||||
|
||||
impl mlua::UserData for SignalProcessingWrapper
|
||||
{
|
||||
fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M)
|
||||
{
|
||||
methods.add_method("get_energy_in_band", |_, this, (start_freq, end_freq): (f32, f32)| {
|
||||
Ok(this.signal_processing.borrow().get_energy_in_band(start_freq, end_freq))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue