Skip to main content

register

Function register 

Source
pub fn register(ext: Extension) -> Result<()>
Expand description

Add a block to the registry: it is listed by registry, built by build, described by json_schema and checked by check_link like the others. A crate that defines blocks registers them before it runs a specification, and may ship its own comnum binary around cli::main.

§Errors

Error::Config when a block of that name exists.

§Examples

A block of another crate: its parameters are declared with block_params! and its ports with block_info!, as those of the blocks of this crate, so that comnum blocks, the JSON Schema and the checks of the links describe it too.

use comnum_core::rng::Rng;
use comnum_spec::blocks::{self, Block, BuildContext, Extension, Frame, Params};
use comnum_spec::{RunOptions, Spec, block_info, block_params, run};
use serde_json::Value as Json;

block_params! {
    struct GainSpec {
        gain_db: f64 [0.0] "dB", "power gain";
    }
}

/// Multiply every sample by an amplitude gain.
struct Gain(f64);

impl Block for Gain {
    fn apply(&self, s: &mut Frame, _: &mut Rng) -> comnum_core::Result<()> {
        s.streams_mut().flatten().for_each(|v| *v *= self.0);
        Ok(())
    }
}

fn build(p: Json, _label: String, _: &BuildContext) -> comnum_core::Result<Box<dyn Block>> {
    let q = GainSpec::parse("gain", p)?;
    Ok(Box::new(Gain(comnum_math::db2amp(q.gain_db))))
}

blocks::register(Extension {
    info: block_info!("gain", "Amplify the samples.", GainSpec, needs [Samples], gives []),
    build,
})?;
let spec = Spec::from_yaml(
    "name: amplified\nlink: [source, {type: gain, gain_db: 6}]\n\
     metrics: {report: [ser]}\nstop: {max_trials: 2}",
)?;
let results = run(&spec, &RunOptions::default())?;
assert_eq!(results[0].metric("ser").unwrap().value(), 0.0);
// listed with its parameters, and checked as the blocks of this crate
let info = blocks::registry().into_iter().find(|b| b.name == "gain").unwrap();
assert_eq!((info.params[0].name, info.params[0].unit), ("gain_db", "dB"));
let unknown = serde_json::json!({"type": "gain", "gain": 6});
assert!(blocks::build(&unknown, &BuildContext::default()).is_err());