コンテンツにスキップ
これは開発版のドキュメントである. 内容は次のリリースまでに変更される可能性がある. 最新のリリース版は 0.6.x を参照.

PatternStm

PatternStm は, ハードウェアタイマにより任意の音場 (各振動子の emission) を切り替える STM 機能を提供する. FociStm と異なり, 任意の Pattern を扱えるが, 転送フレーム数が多い (=レイテンシが大きい).

PatternStm::new(freq, &patterns, option);
引数 説明
freq impl Into<StmConfig> 再生レート (Freq / Duration / SamplingConfig)
patterns &[Vec<Vec<Emission>>] Pattern サンプルの列 (2 サンプル以上)
option PatternStmOption 転送モード・ループ・遷移などのオプション

freqFreq / Duration を渡すと「全サンプルを 1 周する周波数/周期」を表す. サンプリング周波数を指定することもできる. Duration がサンプル数で割り切れない場合はエラーになる (丸めたいときは Nearest を使う).

PatternStmOption {
bank,
mode,
loop_behavior,
transition_mode,
}
フィールド デフォルト 説明
bank PatternBank PatternBank::B0 書き込み先・再生対象のバンク
mode PatternStmMode PatternStmMode::PhaseIntensityFull 転送形式
loop_behavior LoopBehavior LoopBehavior::Infinite ループ回数
transition_mode TransitionMode TransitionMode::Immediate バンク切替時の遷移タイミング

loop_behaviortransition_mode の挙動は再生制御 を参照.

各 Pattern の転送形式を選ぶ. 位相のみ・低分解能の形式は転送フレーム数を減らせる.

モード 内容
PhaseIntensityFull 位相・振幅をそのまま転送 (デフォルト)
PhaseFull 位相のみ転送. 振幅は最大に固定
PhaseHalf 位相を 4 bit に圧縮して転送

PatternStm は内部で WritePatternBuffer (各 index) + ConfigPattern + ChangePatternBank の 3 つへ展開される. 以下は PatternStm::new(freq, &patterns, option) と等価な組み合わせである.

PatternStmModePhaseFull / PhaseHalf のときは, WritePatternBuffer の代わりに WritePatternCompressed が使われる.

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?;