Macro for complex filters works

This commit is contained in:
Sebastian 2023-07-27 18:53:46 +02:00
parent 081c5ac2e6
commit e7bc2f3d36
4 changed files with 139 additions and 53 deletions

57
Cargo.lock generated
View File

@ -28,9 +28,10 @@ name = "firls-rs-macros"
version = "0.1.0"
dependencies = [
"firls_rs",
"num",
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.27",
]
[[package]]
@ -54,9 +55,9 @@ dependencies = [
[[package]]
name = "nalgebra"
version = "0.32.2"
version = "0.32.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511"
checksum = "307ed9b18cc2423f29e83f84fd23a8e73628727990181f18641a8b5dc2ab1caa"
dependencies = [
"approx",
"matrixmultiply",
@ -70,9 +71,9 @@ dependencies = [
[[package]]
name = "nalgebra-macros"
version = "0.2.0"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d232c68884c0c99810a5a4d333ef7e47689cfd0edc85efc9e54e1e6bf5212766"
checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998"
dependencies = [
"proc-macro2",
"quote",
@ -81,9 +82,9 @@ dependencies = [
[[package]]
name = "num"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606"
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
@ -148,33 +149,33 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
dependencies = [
"autocfg",
]
[[package]]
name = "paste"
version = "1.0.13"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "proc-macro2"
version = "1.0.64"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78803b62cbf1f46fde80d7c0e803111524b9877184cfe7c3033659490ac7a7da"
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.29"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105"
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
dependencies = [
"proc-macro2",
]
@ -187,9 +188,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "safe_arch"
version = "0.7.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62a7484307bd40f8f7ccbacccac730108f2cae119a3b11c74485b48aa9ea650f"
checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354"
dependencies = [
"bytemuck",
]
@ -220,9 +221,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.23"
version = "2.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737"
checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0"
dependencies = [
"proc-macro2",
"quote",
@ -231,22 +232,22 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.43"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42"
checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.43"
version = "1.0.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f"
checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.23",
"syn 2.0.27",
]
[[package]]
@ -257,15 +258,15 @@ checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
[[package]]
name = "unicode-ident"
version = "1.0.10"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73"
checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c"
[[package]]
name = "wide"
version = "0.7.10"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40018623e2dba2602a9790faba8d33f2ebdebf4b86561b83928db735f8784728"
checksum = "aa469ffa65ef7e0ba0f164183697b89b854253fd31aeb92358b7b6155177d62f"
dependencies = [
"bytemuck",
"safe_arch",

View File

@ -8,6 +8,7 @@ proc-macro = true
[dependencies]
firls_rs = { path = "../firls-rs" }
num = "0.4.1"
proc-macro2 = "1.0.64"
quote = "1.0.29"
syn = {version="2.0.23", features=["full"]}

View File

@ -0,0 +1,20 @@
use firls_rs_macros::firls_complex;
use num::Complex;
const COEFFS: [Complex<f32>; 23] = firls_complex!(
23,
8000.0,
[(0.0, 1.0), (1200.0, 1.0), (1500.0, 0.0), (4000.0, 0.0)],
1500.0
);
fn main() {
println!("[");
for coeff in COEFFS.iter() {
println!("{},", coeff)
}
println!("]");
println!("Lenght: {}", COEFFS.len());
}

View File

@ -1,15 +1,39 @@
extern crate num;
extern crate proc_macro;
extern crate quote;
use firls_rs::firls;
use firls_rs::{firls, frequency_shift_coeffs};
use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::quote;
use syn::parse::{Parse, ParseStream};
use syn::parse_macro_input;
use syn::spanned::Spanned;
use syn::{parse_macro_input};
use syn::{punctuated::Punctuated, Expr, Lit, Token};
#[proc_macro]
pub fn firls_real(input: TokenStream) -> TokenStream {
let FirlsRealInput {
filter_len,
sampling_frequency,
bands,
span,
} = parse_macro_input!(input as FirlsRealInput);
let output = match firls(filter_len, sampling_frequency, &bands) {
Ok(coeffs) => {
quote! {
[
#(#coeffs),*
]
}
}
Err(msg) => syn::Error::new(span, msg).to_compile_error(),
};
proc_macro::TokenStream::from(output)
}
struct FirlsRealInput {
filter_len: usize,
sampling_frequency: f32,
@ -37,6 +61,69 @@ impl Parse for FirlsRealInput {
}
}
#[proc_macro]
pub fn firls_complex(input: TokenStream) -> TokenStream {
let FirlsComplexInput {
filter_len,
sampling_frequency,
bands,
frequency_shift,
span,
} = parse_macro_input!(input as FirlsComplexInput);
let output = match firls(filter_len, sampling_frequency, &bands) {
Ok(coeffs) => {
let coeffs = frequency_shift_coeffs(&coeffs, sampling_frequency, frequency_shift);
let constructors: Vec<proc_macro2::TokenStream> = coeffs
.iter()
.map(|num::Complex::<f32> { re, im }| {
quote! {
num::Complex::<f32> {re: #re, im: #im}
}
})
.collect();
quote! {
[
#(#constructors),*
]
}
}
Err(msg) => syn::Error::new(span, msg).to_compile_error(),
};
proc_macro::TokenStream::from(output)
}
struct FirlsComplexInput {
filter_len: usize,
sampling_frequency: f32,
bands: Vec<(f32, f32)>,
frequency_shift: f32,
span: Span,
}
impl Parse for FirlsComplexInput {
fn parse(input: ParseStream) -> Result<Self, syn::Error> {
let arg_list = Punctuated::<Expr, Token![,]>::parse_separated_nonempty(input)?;
if arg_list.len() != 4 {
return Err(syn::Error::new(
arg_list.span(),
"firls_complex takes 4 parameters",
));
}
Ok(FirlsComplexInput {
filter_len: parse_filter_len(&arg_list[0])?,
sampling_frequency: parse_frequency(&arg_list[1])?,
bands: parse_band_list(&arg_list[2])?,
frequency_shift: parse_frequency(&arg_list[3])?,
span: arg_list.span(),
})
}
}
fn parse_filter_len(len: &Expr) -> Result<usize, syn::Error> {
match len {
Expr::Lit(expr) => match &expr.lit {
@ -122,26 +209,3 @@ fn parse_band_tuple(tuple: &Expr) -> Result<(f32, f32), syn::Error> {
)),
}
}
#[proc_macro]
pub fn firls_real(input: TokenStream) -> TokenStream {
let FirlsRealInput {
filter_len,
sampling_frequency,
bands,
span,
} = parse_macro_input!(input as FirlsRealInput);
let output = match firls(filter_len, sampling_frequency, &bands) {
Ok(coeffs) => {
quote! {
[
#(#coeffs),*
]
}
}
Err(msg) => syn::Error::new(span, msg).to_compile_error(),
};
proc_macro::TokenStream::from(output)
}