use super::NamModel;
use super::sealed;
pub mod head_projection;
pub mod layer;
pub mod layer_dyn;
pub mod layer_dyn_kernels;
pub mod layer_kernels;
pub mod model1;
pub mod model2;
pub mod model_dyn;
pub mod prewarm;
pub use layer::LstmLayer;
pub use layer_dyn::LstmLayerDyn;
pub use model_dyn::LstmModelDyn;
pub use model1::LstmModel1;
pub use model2::LstmModel2;
pub const fn lstm_weight_count(num_layers: usize, hidden_size: usize) -> usize {
let h = hidden_size;
if num_layers == 1 {
4 * h * (1 + h) + 7 * h + 1
} else {
12 * h * h + 17 * h + 1
}
}
pub type Lstm1x3 = LstmModel1<3, 4, 12>;
pub type Lstm1x8 = LstmModel1<8, 9, 32>;
pub type Lstm1x12 = LstmModel1<12, 13, 48>;
pub type Lstm1x16 = LstmModel1<16, 17, 64>;
pub type Lstm1x24 = LstmModel1<24, 25, 96>;
pub type Lstm1x40 = LstmModel1<40, 41, 160>;
pub type Lstm2x8 = LstmModel2<8, 9, 16, 32>;
pub type Lstm2x12 = LstmModel2<12, 13, 24, 48>;
pub type Lstm2x16 = LstmModel2<16, 17, 32, 64>;
pub type Lstm2x24 = LstmModel2<24, 25, 48, 96>;
impl<const H: usize, const H1_IH: usize, const H_H4: usize> sealed::Sealed
for LstmModel1<H, H1_IH, H_H4>
{
}
impl<const H: usize, const H1_IH: usize, const H2_IH: usize, const H_H4: usize> sealed::Sealed
for LstmModel2<H, H1_IH, H2_IH, H_H4>
{
}
impl sealed::Sealed for LstmModelDyn {}
impl<const H: usize, const H1_IH: usize, const H_H4: usize> NamModel
for LstmModel1<H, H1_IH, H_H4>
{
fn process(&mut self, input: &[f32], output: &mut [f32]) {
self.process(input, output);
}
#[cold]
fn prewarm(&mut self, num_samples: usize) {
lstm_prewarm_common(self, num_samples);
}
fn reset(&mut self, _sample_rate: u32, _max_buffer_size: usize) -> anyhow::Result<()> {
self.reset_states();
if self.prewarm_on_reset() {
self.prewarm(self.prewarm_samples());
}
Ok(())
}
fn prewarm_samples(&self) -> usize {
let result = (0.5 * self.expected_sample_rate) as isize;
if result <= 0 { 1 } else { result as usize }
}
fn prewarm_on_reset(&self) -> bool {
self.prewarm_on_reset
}
fn set_prewarm_on_reset(&mut self, val: bool) {
self.prewarm_on_reset = val;
}
}
impl<const H: usize, const H1_IH: usize, const H2_IH: usize, const H_H4: usize> NamModel
for LstmModel2<H, H1_IH, H2_IH, H_H4>
{
fn process(&mut self, input: &[f32], output: &mut [f32]) {
self.process(input, output);
}
#[cold]
fn prewarm(&mut self, num_samples: usize) {
lstm_prewarm_common(self, num_samples);
}
fn reset(&mut self, _sample_rate: u32, _max_buffer_size: usize) -> anyhow::Result<()> {
self.reset_states();
if self.prewarm_on_reset() {
self.prewarm(self.prewarm_samples());
}
Ok(())
}
fn prewarm_samples(&self) -> usize {
let result = (0.5 * self.expected_sample_rate) as isize;
if result <= 0 { 1 } else { result as usize }
}
fn prewarm_on_reset(&self) -> bool {
self.prewarm_on_reset
}
fn set_prewarm_on_reset(&mut self, val: bool) {
self.prewarm_on_reset = val;
}
}
impl NamModel for LstmModelDyn {
fn process(&mut self, input: &[f32], output: &mut [f32]) {
self.process(input, output);
}
#[cold]
fn prewarm(&mut self, num_samples: usize) {
lstm_prewarm_common(self, num_samples);
}
fn reset(&mut self, _sample_rate: u32, _max_buffer_size: usize) -> anyhow::Result<()> {
self.reset_states();
if self.prewarm_on_reset() {
self.prewarm(self.prewarm_samples());
}
Ok(())
}
fn prewarm_samples(&self) -> usize {
let result = (0.5 * self.expected_sample_rate) as isize;
if result <= 0 { 1 } else { result as usize }
}
fn prewarm_on_reset(&self) -> bool {
self.prewarm_on_reset
}
fn set_prewarm_on_reset(&mut self, val: bool) {
self.prewarm_on_reset = val;
}
}
use self::prewarm::*;
#[cfg(test)]
mod lstm_test;