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::signal_processing::SignalProcessing;
|
||||||
use crate::userscript::UserScript;
|
use crate::userscript::UserScript;
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
fn main()
|
fn main()
|
||||||
{
|
{
|
||||||
let mut stdin = std::io::stdin();
|
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
|
// set up signal processing
|
||||||
|
|
||||||
println!("Initializing 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…");
|
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_bass = sigproc.borrow().get_energy_in_band( 0.0, 400.0);
|
||||||
let energy_mid = sigproc.get_energy_in_band( 400.0, 4000.0);
|
let energy_mid = sigproc.borrow().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_treble = sigproc.borrow().get_energy_in_band(4000.0, config::SAMP_RATE/2.0);
|
||||||
|
|
||||||
// dump the output
|
// dump the output
|
||||||
println!("Bass: {:11.2} – Mid: {:11.2} – Treble: {:11.2}", energy_bass, energy_mid, energy_treble);
|
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::config;
|
||||||
|
use crate::signal_processing::SignalProcessing;
|
||||||
|
|
||||||
use mlua::Lua;
|
use mlua::Lua;
|
||||||
use mlua::FromLua;
|
use mlua::FromLua;
|
||||||
use mlua::Error;
|
use mlua::Error;
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
|
||||||
pub struct UserScript
|
pub struct UserScript
|
||||||
{
|
{
|
||||||
lua_state: Lua,
|
lua_state: Lua,
|
||||||
|
@ -33,12 +37,26 @@ pub struct UserScript
|
||||||
|
|
||||||
impl 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 {
|
let s = UserScript {
|
||||||
lua_state: Lua::new(),
|
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
|
// load the user script and execute it to make variables and functions available
|
||||||
let user_script = std::fs::read_to_string(user_script_path)?;
|
let user_script = std::fs::read_to_string(user_script_path)?;
|
||||||
s.lua_state.load(&user_script).exec()?;
|
s.lua_state.load(&user_script).exec()?;
|
||||||
|
@ -93,3 +111,23 @@ impl UserScript
|
||||||
Ok(())
|
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