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

PatternStm

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

PatternStm::new(config, &patterns, intensities, option);
引数 型 説明
config SamplingConfig サンプル毎のサンプリング設定
phases &[Vec<Vec<Phase>>] 各サンプルの位相の列 (2 サンプル以上)
intensities impl Into<StmIntensity> 全サンプルの振幅 (一様値 / 全 index 共通バッファ / index 毎のバッファ列)
option PatternStmOption 位相のビット幅・ループ・遷移などのオプション

config は 1 サンプルあたりのサンプリング設定である.

intensities には以下の3つの型が渡せる.

  • Intensity : 全デバイス・全振動子・全indexで同じ値を使う場合
  • &[Vec<Intensity>] : 振動子ごとには異なるが全indexで共通の値を使う場合
  • &[Vec<Vec<Intensity>>] : 全indexごとに異なる値を使う場合
PatternStmOption {
bank,
phase_depth,
loop_behavior,
transition_mode,
..Default::default()
}
フィールド 型 デフォルト 説明
bank PatternBank PatternBank::B0 書き込み先・再生対象のバンク
phase_depth PhaseDepth PhaseDepth::Bits8 位相のビット幅
loop_behavior LoopBehavior LoopBehavior::Infinite ループ回数
transition_mode TransitionMode TransitionMode::Immediate バンク切替時の遷移タイミング

loop_behavior と transition_mode の挙動は再生制御 を参照.

intensities PhaseDepth::Bits8 PhaseDepth::Bits4
Intensity WritePatternPhase (5 index/フレーム) WritePatternPhase (11 index/フレーム)
&[Vec<Intensity>] / &[Vec<Vec<Intensity>>] WritePatternBuffer (2 index/フレーム) エラー

Bits4 は位相を上位 4 bit に量子化する.

PatternStm は内部で WritePatternPhase または WritePatternBuffer + ConfigPattern + ActivatePatternBank の 3 つへ展開される. 以下は intensities が一様値のときの PatternStm::new(config, &phases, intensities, option) と等価な組み合わせである. intensities が振動子ごとの値のときは WritePatternPhase の代わりに WritePatternBuffer が 2 index ずつ使われる.

let max_count = option.phase_depth.max_count();
for (k, chunk) in patterns.chunks(max_count).enumerate() {
WritePatternPhase {
bank: option.bank,
start_index: k * max_count,
depth: option.phase_depth,
intensity: intensities,
patterns: chunk,
};
}
ConfigPattern {
bank: option.bank,
config,
size: patterns.len(),
loop_behavior: option.loop_behavior,
};
ActivatePatternBank {
bank: option.bank,
transition_mode: option.transition_mode,
};
use autd3_rs::commands::{Clear, PatternStm, PatternStmOption, PhaseDepth, Synchronize};
use autd3_rs::geometry::{Autd3, Geometry, offset};
use autd3_rs::units::{Hz, m, mm, s};
use autd3_rs::value::{Intensity, LoopBehavior, PatternBank, SamplingConfig, TransitionMode};
use autd3_rs::Client;
use autd3_rs::udp::TransportOption;
use autd3_rs_pattern::{focus, wavelength};
let geometry = Geometry::new(vec![Autd3::default()]);
let option = TransportOption::default();
let mut client = Client::open(&geometry, &option).await?;
client.send(Clear).await?;
client.send(Synchronize).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.phase_buffer();
focus(
&geometry,
target,
wavelength,
&mut buffer,
);
buffer
})
.collect::<Vec<_>>();
client.send(PatternStm::new(
SamplingConfig::from_freq(1.0 * Hz * patterns.len() as f32)?,
&patterns,
Intensity::MAX,
PatternStmOption {
bank: PatternBank::B0,
phase_depth: PhaseDepth::Bits8,
loop_behavior: LoopBehavior::Infinite,
transition_mode: TransitionMode::Immediate,
..Default::default()
},
)).await?;