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.

Bank Switching

As explained in Moving the Focal Point, in AUTD3 a Pattern and the like are overwritten each time they are sent, and this write is not buffered. As a result, overwriting data that is being played back can cause unintended intermediate data to be output partway through the write.

To prevent this, the AUTD3 Pattern has multiple memory regions (called banks). By writing to a bank that is not currently being played back and then switching the playback target to that bank after the write completes, the data can be swapped without disturbing the output.

The write-target / playback-target bank is specified with Pattern::with_bank. Pattern::new (when the bank is omitted) uses PatternBank::B0.

In the example below, focus A is first written to B0 and played back, and the next focus B is written to B1, which is not being played back. The output of B0 is not disturbed even while writing to B1, and after the write completes it switches to B1.

// Write focus A to bank B0 and play it.
let target_a = geometry.center() + offset(0.0 * mm, 0.0 * mm, 150.0 * mm);
let mut pat_a = geometry.pattern_buffer();
autd3_rs_pattern::focus(
&geometry,
target_a,
wavelength,
&autd3_rs_pattern::FocusOption::default(),
&mut pat_a,
);
let mut builder = client.datagram_builder();
builder.push(Pattern::with_bank(PatternBank::B0, &pat_a));
for frame in &builder.build()? {
client.send_checked(frame).await?;
}
// Write focus B to bank B1, which is not currently playing, then switch to B1.
// B0 keeps playing cleanly while B1 is being written (double buffering).
let target_b = geometry.center() + offset(0.0 * mm, 30.0 * mm, 150.0 * mm);
let mut pat_b = geometry.pattern_buffer();
autd3_rs_pattern::focus(
&geometry,
target_b,
wavelength,
&autd3_rs_pattern::FocusOption::default(),
&mut pat_b,
);
let mut builder = client.datagram_builder();
builder.push(Pattern::with_bank(PatternBank::B1, &pat_b));
for frame in &builder.build()? {
client.send_checked(frame).await?;
}

By writing alternately to the bank that is not being played back in this way, the pattern can be swapped without disturbing the output.

Modulation also has banks, and the write-target bank (ModulationBank) can be specified with Modulation::with_bank.

For finer control over bank writing, configuration, and switching, refer to the low-level commands in the API reference.