1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use crate::geometry::Vector3;
use crate::{consts::DataArray, geometry::Geometry};
use crate::{consts::NUM_TRANS_IN_UNIT, Float};
use super::super::adjust_amp;
use super::super::Gain;
pub struct PlaneWaveGain {
dir: Vector3,
duty: u8,
data: Option<Vec<DataArray>>,
}
impl PlaneWaveGain {
pub fn create(dir: Vector3) -> Self {
Self::create_with_duty(dir, 0xff)
}
pub fn create_with_amp(dir: Vector3, amp: Float) -> Self {
Self::create_with_duty(dir, adjust_amp(amp))
}
pub fn create_with_duty(dir: Vector3, duty: u8) -> Self {
PlaneWaveGain {
dir,
duty,
data: None,
}
}
}
impl Gain for PlaneWaveGain {
fn get_data(&self) -> &[DataArray] {
assert!(self.data.is_some());
match &self.data {
Some(data) => data,
None => panic!(),
}
}
fn build(&mut self, geometry: &Geometry) {
if self.data.is_some() {
return;
}
let num_devices = geometry.num_devices();
let mut data = Vec::with_capacity(num_devices);
let dir = self.dir;
let duty = (self.duty as u16) << 8;
let wavelength = geometry.wavelength();
for dev in 0..num_devices {
let mut buf: DataArray = unsafe { std::mem::zeroed() };
for (i, b) in buf.iter_mut().enumerate().take(NUM_TRANS_IN_UNIT) {
let trp = geometry.position_by_local_idx(dev, i);
let dist = dir.dot(&trp);
let phase = (dist % wavelength) / wavelength;
let phase = (255.0 * (1.0 - phase)) as u16;
*b = duty | phase;
}
data.push(buf);
}
self.data = Some(data);
}
}