seek_record/
seek_record.rs1use std::env;
2use wfdb::Record;
3
4fn main() -> wfdb::Result<()> {
5 let args: Vec<String> = env::args().collect();
6
7 if args.len() < 2 {
8 eprintln!("Usage: {} <record_path>", args[0]);
9 eprintln!("\nExample:");
10 eprintln!(" {} ./references/wfdb-master/data/100s", args[0]);
11 std::process::exit(1);
12 }
13
14 let record_path = &args[1];
15 let record = Record::open(record_path)?;
16
17 println!("=== Record Information ===");
18 println!("Record: {}", record.metadata().name());
19 println!(
20 "Sampling frequency: {} Hz",
21 record.metadata().sampling_frequency()
22 );
23
24 if let Some(num_samples) = record.metadata().num_samples {
25 println!("Total samples: {num_samples}");
26 }
27
28 if record.is_multi_segment() {
29 demonstrate_multi_segment_seeking(&record)?;
30 } else {
31 demonstrate_single_segment_seeking(&record)?;
32 }
33
34 Ok(())
35}
36
37#[allow(clippy::unwrap_used)]
38fn demonstrate_single_segment_seeking(record: &Record) -> wfdb::Result<()> {
39 println!("\n=== Single-Segment Record ===");
40 println!("Signals: {}", record.signal_count());
41
42 if record.signal_count() == 0 {
43 println!("No signals to read");
44 return Ok(());
45 }
46
47 let signal_idx = 0;
48 let signal_info = &record.signal_info().unwrap()[signal_idx];
49 println!(
50 "\nDemonstrating with Signal {}: {}",
51 signal_idx,
52 signal_info
53 .description
54 .as_deref()
55 .unwrap_or("(no description)")
56 );
57
58 println!("\n--- SignalReader: Sample-based Seeking ---");
59 let mut reader = record.signal_reader(signal_idx)?;
60
61 println!("Reading first 5 samples from start...");
62 let samples = reader.read_samples(5)?;
63 println!(" Samples 0-4: {samples:?}");
64 println!(" Current position: {}", reader.position());
65
66 println!("\nSeeking to sample 100...");
67 match reader.seek_to_sample(100) {
68 Ok(pos) => {
69 println!(" Seek to position: {pos}");
70 let samples = reader.read_samples(5)?;
71 println!(" Samples 100-104: {samples:?}");
72 println!(" Current position: {}", reader.position());
73
74 println!("\nSeeking backward to sample 50...");
75 reader.seek_to_sample(50)?;
76 let samples = reader.read_samples(3)?;
77 println!(" Samples 50-52: {samples:?}");
78 println!(" Current position: {}", reader.position());
79 }
80 Err(e) => {
81 println!(" Seeking not supported for this format: {e}");
82 }
83 }
84
85 println!("\n--- SignalReader: Time-based Seeking ---");
86 let mut reader = record.signal_reader(signal_idx)?;
87
88 println!("Seeking to 1.0 second...");
89 match reader.seek_to_time(1.0) {
90 Ok(pos) => {
91 println!(" Seek to sample position: {pos}");
92 println!(
93 " (1.0 sec × {} Hz = {} samples)",
94 record.metadata().sampling_frequency(),
95 pos
96 );
97 let samples = reader.read_samples(3)?;
98 println!(" Samples at 1.0s: {samples:?}");
99 }
100 Err(e) => {
101 println!(" Time-based seeking failed: {e}");
102 }
103 }
104
105 println!("\n--- MultiSignalReader: Frame-based Seeking ---");
106 let mut multi_reader = record.multi_signal_reader()?;
107
108 println!("Reading first 3 frames...");
109 let frames = multi_reader.read_frames(3)?;
110 for (i, frame) in frames.iter().enumerate() {
111 println!(" Frame {i}: {frame:?}");
112 }
113 println!(" Current position: frame {}", multi_reader.position());
114
115 println!("\nSeeking to frame 50...");
116 match multi_reader.seek_to_frame(50) {
117 Ok(pos) => {
118 println!(" Seek to frame: {pos}");
119 let frames = multi_reader.read_frames(2)?;
120 for (i, frame) in frames.iter().enumerate() {
121 println!(" Frame {}: {:?}", 50 + i, frame);
122 }
123 println!(" Current position: frame {}", multi_reader.position());
124 }
125 Err(e) => {
126 println!(" Frame seeking not supported: {e}");
127 }
128 }
129
130 println!("\n--- Physical Units Conversion ---");
131 let mut reader = record.signal_reader(signal_idx)?;
132
133 println!(
134 "Signal gain: {} ADC units per {}",
135 reader.gain(),
136 reader.units()
137 );
138 println!("Signal baseline: {} ADC units", reader.baseline());
139
140 let adc_values = reader.read_samples(5)?;
141 println!("\nFirst 5 ADC values: {adc_values:?}");
142
143 reader.seek_to_sample(0)?;
144 let physical_values = reader.read_physical(5)?;
145 println!("First 5 physical values: {physical_values:?}");
146
147 println!("\nConversion example:");
148 for i in 0..adc_values.len().min(3) {
149 let adc = adc_values[i];
150 let physical = physical_values[i];
151 println!(" ADC {} → {} {}", adc, physical, reader.units());
152 }
153
154 Ok(())
155}
156
157fn demonstrate_multi_segment_seeking(record: &Record) -> wfdb::Result<()> {
158 println!("\n=== Multi-Segment Record ===");
159 println!("Segments: {}", record.segment_count());
160
161 if let Some(segments) = record.segment_info() {
162 println!("\nSegment details:");
163 for (i, seg) in segments.iter().enumerate() {
164 println!(
165 " Segment {}: {} ({} samples)",
166 i, seg.record_name, seg.num_samples
167 );
168 }
169 }
170
171 println!("\n--- SegmentReader: Cross-segment Seeking ---");
172 let mut reader = record.segment_reader()?;
173
174 println!("Reading first 5 frames...");
175 let frames = reader.read_frames(5)?;
176 for (i, frame) in frames.iter().enumerate() {
177 println!(" Frame {i}: {frame:?}");
178 }
179 println!(
180 " Current position: sample {} (segment {})",
181 reader.position(),
182 reader.current_segment()
183 );
184
185 println!("\nSeeking to sample 100...");
186 match reader.seek_to_sample(100) {
187 Ok(pos) => {
188 println!(" Seek to sample: {pos}");
189 println!(" Now at segment: {}", reader.current_segment());
190
191 let frames = reader.read_frames(3)?;
192 for (i, frame) in frames.iter().enumerate() {
193 println!(" Frame {}: {:?}", 100 + i, frame);
194 }
195 println!(" Current position: sample {}", reader.position());
196 }
197 Err(e) => {
198 println!(" Seeking failed: {e}");
199 }
200 }
201
202 println!("\nReading sequentially across segments...");
203 reader.seek_to_sample(0)?;
204 let mut frame_count = 0;
205 while let Some(_frame) = reader.read_frame()? {
206 frame_count += 1;
207 if frame_count >= 10 {
208 println!(" Read {frame_count} frames across segments...");
209 break;
210 }
211 }
212 println!(
213 " Final position: sample {} (segment {})",
214 reader.position(),
215 reader.current_segment()
216 );
217
218 Ok(())
219}