Skip to content
This is the development version of the documentation. It may change before the next release. See 0.6.x for the latest release.

PatternStm

PatternStm provides an STM feature that switches arbitrary sound fields (the emission of each transducer) by a hardware timer. Unlike FociStm, it can handle arbitrary Patterns, but the number of frames to transfer is large (i.e. the latency is high).

PatternStm::new(freq, &patterns, option);
Parameter Type Description
freq impl Into<StmConfig> Playback rate (Freq / Duration / SamplingConfig)
patterns &[Vec<Vec<Emission>>] Sequence of Pattern samples (at least 2 samples)
option PatternStmOption Options such as transfer mode, loop, and transition

Passing a Freq / Duration to freq represents “the frequency/period for one full cycle over all samples”. A sampling frequency can also be specified. A Duration that is not divisible by the number of samples is an error (use Nearest to round it).

PatternStmOption {
bank,
mode,
loop_behavior,
transition_mode,
}
Field Type Default Description
bank PatternBank PatternBank::B0 Bank to write to / play back
mode PatternStmMode PatternStmMode::PhaseIntensityFull Transfer format
loop_behavior LoopBehavior LoopBehavior::Infinite Loop count
transition_mode TransitionMode TransitionMode::Immediate Transition timing on bank switching

For the behavior of loop_behavior and transition_mode, see playback control.

Selects the transfer format of each Pattern. The phase-only and low-resolution formats can reduce the number of frames to transfer.

Mode Content
PhaseIntensityFull Transfer phase and amplitude as-is (default)
PhaseFull Transfer phase only. Amplitude fixed at maximum
PhaseHalf Compress phase to 4 bit and transfer

PatternStm internally expands into the three commands WritePatternBuffer (each index) + ConfigPattern + ChangePatternBank. The following is equivalent to PatternStm::new(freq, &patterns, option).

When PatternStmMode is PhaseFull / PhaseHalf, WritePatternCompressed is used instead of WritePatternBuffer.

for (index, pattern) in patterns.iter().enumerate() {
WritePatternBuffer {
bank: option.bank,
index,
emissions: pattern.as_slice(),
};
}
ConfigPattern {
bank: option.bank,
config: StmConfig::new(freq).into_sampling_config(patterns.len()),
size: patterns.len(),
loop_behavior: option.loop_behavior,
};
ChangePatternBank {
bank: option.bank,
transition_mode: option.transition_mode,
};
use autd3_rs::commands::{PatternStm, PatternStmMode, PatternStmOption};
use autd3_rs::geometry::{Autd3, Geometry, offset};
use autd3_rs::units::{Hz, m, mm, s};
use autd3_rs::value::{LoopBehavior, PatternBank, TransitionMode};
use autd3_rs::{Client, ClientConfig};
use autd3_rs_link_nop::Nop;
use autd3_rs_pattern::{FocusOption, focus, wavelength};
let geometry = Geometry::new(vec![Autd3::default()]);
let client = Client::open(&geometry, Nop, ClientConfig::default()).await?;
let center = geometry.center() + offset(0.0 * mm, 0.0 * mm, 150.0 * mm);
let wavelength = wavelength(340.0 * m / s);
let patterns = (0..200)
.map(|i| {
let theta = 2.0 * std::f32::consts::PI * i as f32 / 200.0;
let target =
center + offset(30.0 * theta.cos() * mm, 30.0 * theta.sin() * mm, 0.0 * mm);
let mut buffer = geometry.pattern_buffer();
focus(
&geometry,
target,
wavelength,
&FocusOption::default(),
&mut buffer,
);
buffer
})
.collect::<Vec<_>>();
let mut builder = client.datagram_builder();
builder.push(PatternStm::new(
1.0 * Hz,
&patterns,
PatternStmOption {
bank: PatternBank::B0,
mode: PatternStmMode::PhaseIntensityFull,
loop_behavior: LoopBehavior::Infinite,
transition_mode: TransitionMode::Immediate,
},
));
let frames = builder.build()?;
for frame in &frames {
client.send_checked(frame).await?;
}
client.close().await?;