1use crate::bindings::{
2 AudioBeamMode, BOOLEAN, BYTE, IAudioBeam, IAudioBeamFrame, IAudioBeamFrameArrivedEventArgs,
3 IAudioBeamFrameList, IAudioBeamFrameReader, IAudioBeamFrameReference, IAudioBeamList,
4 IAudioBeamSubFrame, IAudioBodyCorrelation, IFrameCapturedEventArgs, IKinectSensor,
5 KinectAudioCalibrationState, TIMESPAN, UINT64, WAITABLE_HANDLE,
6};
7use crate::bindings::{IAudioSource, UINT};
8use crate::frame::FrameCapturedEventArgs;
9use crate::kinect::KinectSensor;
10use std::ptr;
11use windows::Win32::Foundation::{E_FAIL, E_POINTER, HANDLE};
12use windows::Win32::System::Com::IStream;
13use windows::core::{Error, Interface};
14
15pub struct AudioSource {
16 ptr: *mut IAudioSource,
17}
18
19impl AudioSource {
20 pub(crate) fn new(ptr: *mut IAudioSource) -> Self {
21 assert!(!ptr.is_null());
22 Self { ptr }
23 }
24
25 pub fn subscribe_frame_captured(&self) -> Result<WAITABLE_HANDLE, Error> {
26 if self.ptr.is_null() {
27 return Err(Error::from(E_POINTER));
28 }
29 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
30 let subscribe_fn = vtbl
31 .SubscribeFrameCaptured
32 .ok_or_else(|| Error::from(E_FAIL))?;
33 let mut waitable_handle: WAITABLE_HANDLE = HANDLE::default();
34 let hr = unsafe { subscribe_fn(self.ptr, &mut waitable_handle) };
35 if hr.is_err() {
36 Err(Error::from_hresult(hr))
37 } else {
38 Ok(waitable_handle)
39 }
40 }
41
42 pub fn unsubscribe_frame_captured(
43 &self,
44 waitable_handle: WAITABLE_HANDLE,
45 ) -> Result<(), Error> {
46 if self.ptr.is_null() {
47 return Err(Error::from(E_POINTER));
48 }
49 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
50 let unsubscribe_fn = vtbl
51 .UnsubscribeFrameCaptured
52 .ok_or_else(|| Error::from(E_FAIL))?;
53 let hr = unsafe { unsubscribe_fn(self.ptr, waitable_handle) };
54 if hr.is_err() {
55 Err(Error::from_hresult(hr))
56 } else {
57 Ok(())
58 }
59 }
60
61 pub fn get_frame_captured_event_data(
62 &self,
63 waitable_handle: WAITABLE_HANDLE,
64 ) -> Result<FrameCapturedEventArgs, Error> {
65 if self.ptr.is_null() {
66 return Err(Error::from(E_POINTER));
67 }
68 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
69 let get_data_fn = vtbl
70 .GetFrameCapturedEventData
71 .ok_or_else(|| Error::from(E_FAIL))?;
72 let mut event_args_ptr: *mut IFrameCapturedEventArgs = ptr::null_mut();
73 let hr = unsafe { get_data_fn(self.ptr, waitable_handle, &mut event_args_ptr) };
74 if hr.is_err() {
75 Err(Error::from_hresult(hr))
76 } else {
77 Ok(FrameCapturedEventArgs::new(event_args_ptr))
78 }
79 }
80
81 pub fn get_kinect_sensor(&self) -> Result<KinectSensor, Error> {
82 if self.ptr.is_null() {
83 return Err(Error::from(E_POINTER));
84 }
85 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
86 let get_sensor_fn = vtbl.get_KinectSensor.ok_or_else(|| Error::from(E_FAIL))?;
87 let mut sensor: *mut IKinectSensor = ptr::null_mut();
88 let hr = unsafe { get_sensor_fn(self.ptr, &mut sensor) };
89 if hr.is_err() {
90 Err(Error::from_hresult(hr))
91 } else {
92 Ok(KinectSensor::new(sensor))
93 }
94 }
95
96 pub fn get_is_active(&self) -> Result<bool, Error> {
97 if self.ptr.is_null() {
98 return Err(Error::from(E_POINTER));
99 }
100 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
101 let get_active_fn = vtbl.get_IsActive.ok_or_else(|| Error::from(E_FAIL))?;
102 let mut is_active: BOOLEAN = 0;
103 let hr = unsafe { get_active_fn(self.ptr, &mut is_active) };
104 if hr.is_err() {
105 Err(Error::from_hresult(hr))
106 } else {
107 Ok(is_active != 0)
108 }
109 }
110
111 pub fn get_sub_frame_length_in_bytes(&self) -> Result<UINT, Error> {
112 if self.ptr.is_null() {
113 return Err(Error::from(E_POINTER));
114 }
115 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
116 let get_length_fn = vtbl
117 .get_SubFrameLengthInBytes
118 .ok_or_else(|| Error::from(E_FAIL))?;
119 let mut length: UINT = 0;
120 let hr = unsafe { get_length_fn(self.ptr, &mut length) };
121 if hr.is_err() {
122 Err(Error::from_hresult(hr))
123 } else {
124 Ok(length)
125 }
126 }
127
128 pub fn get_sub_frame_duration(&self) -> Result<TIMESPAN, Error> {
129 if self.ptr.is_null() {
130 return Err(Error::from(E_POINTER));
131 }
132 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
133 let get_duration_fn = vtbl
134 .get_SubFrameDuration
135 .ok_or_else(|| Error::from(E_FAIL))?;
136 let mut duration: TIMESPAN = 0;
137 let hr = unsafe { get_duration_fn(self.ptr, &mut duration) };
138 if hr.is_err() {
139 Err(Error::from_hresult(hr))
140 } else {
141 Ok(duration)
142 }
143 }
144
145 pub fn get_max_sub_frame_count(&self) -> Result<UINT, Error> {
146 if self.ptr.is_null() {
147 return Err(Error::from(E_POINTER));
148 }
149 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
150 let get_count_fn = vtbl
151 .get_MaxSubFrameCount
152 .ok_or_else(|| Error::from(E_FAIL))?;
153 let mut count: UINT = 0;
154 let hr = unsafe { get_count_fn(self.ptr, &mut count) };
155 if hr.is_err() {
156 Err(Error::from_hresult(hr))
157 } else {
158 Ok(count)
159 }
160 }
161
162 pub fn open_reader(&self) -> Result<AudioBeamFrameReader, Error> {
163 if self.ptr.is_null() {
164 return Err(Error::from(E_POINTER));
165 }
166 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
167 let open_reader_fn = vtbl.OpenReader.ok_or_else(|| Error::from(E_FAIL))?;
168 let mut reader: *mut IAudioBeamFrameReader = ptr::null_mut();
169 let hr = unsafe { open_reader_fn(self.ptr, &mut reader) };
170 if hr.is_err() {
171 Err(Error::from_hresult(hr))
172 } else {
173 Ok(AudioBeamFrameReader::new(reader))
174 }
175 }
176
177 pub fn get_audio_beams(&self) -> Result<AudioBeamList, Error> {
178 if self.ptr.is_null() {
179 return Err(Error::from(E_POINTER));
180 }
181 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
182 let get_beams_fn = vtbl.get_AudioBeams.ok_or_else(|| Error::from(E_FAIL))?;
183 let mut audio_beam_list: *mut IAudioBeamList = ptr::null_mut();
184 let hr = unsafe { get_beams_fn(self.ptr, &mut audio_beam_list) };
185 if hr.is_err() {
186 Err(Error::from_hresult(hr))
187 } else {
188 Ok(AudioBeamList::new(audio_beam_list))
189 }
190 }
191
192 pub fn get_audio_calibration_state(&self) -> Result<KinectAudioCalibrationState, Error> {
193 if self.ptr.is_null() {
194 return Err(Error::from(E_POINTER));
195 }
196 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
197 let get_state_fn = vtbl
198 .get_AudioCalibrationState
199 .ok_or_else(|| Error::from(E_FAIL))?;
200 let mut audio_calibration_state: KinectAudioCalibrationState =
201 KinectAudioCalibrationState::Unknown;
202 let hr = unsafe { get_state_fn(self.ptr, &mut audio_calibration_state) };
203 if hr.is_err() {
204 Err(Error::from_hresult(hr))
205 } else {
206 Ok(audio_calibration_state)
207 }
208 }
209}
210
211impl Drop for AudioSource {
212 fn drop(&mut self) {
213 if !self.ptr.is_null() {
214 unsafe {
215 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
216 && let Some(release_fn) = vtbl.Release
217 {
218 release_fn(self.ptr);
219 }
220 }
221 self.ptr = ptr::null_mut();
222 }
223 }
224}
225
226pub struct AudioBeam {
227 ptr: *mut IAudioBeam,
228}
229
230impl AudioBeam {
231 pub(crate) fn new(ptr: *mut IAudioBeam) -> Self {
232 assert!(!ptr.is_null());
233 Self { ptr }
234 }
235
236 pub fn get_audio_source(&self) -> Result<AudioSource, Error> {
237 if self.ptr.is_null() {
238 return Err(Error::from(E_POINTER));
239 }
240 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
241 let get_source_fn = vtbl.get_AudioSource.ok_or_else(|| Error::from(E_FAIL))?;
242 let mut audio_source_ptr: *mut IAudioSource = ptr::null_mut();
243 let hr = unsafe { get_source_fn(self.ptr, &mut audio_source_ptr) };
244 if hr.is_err() {
245 Err(Error::from_hresult(hr))
246 } else if audio_source_ptr.is_null() {
247 Err(Error::from(E_POINTER))
248 } else {
249 Ok(AudioSource::new(audio_source_ptr))
250 }
251 }
252
253 pub fn get_audio_beam_mode(&self) -> Result<AudioBeamMode, Error> {
254 if self.ptr.is_null() {
255 return Err(Error::from(E_POINTER));
256 }
257 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
258 let get_mode_fn = vtbl.get_AudioBeamMode.ok_or_else(|| Error::from(E_FAIL))?;
259 let mut audio_beam_mode: AudioBeamMode = AudioBeamMode::Automatic; let hr = unsafe { get_mode_fn(self.ptr, &mut audio_beam_mode) };
261 if hr.is_err() {
262 Err(Error::from_hresult(hr))
263 } else {
264 Ok(audio_beam_mode)
265 }
266 }
267
268 pub fn put_audio_beam_mode(&self, audio_beam_mode: AudioBeamMode) -> Result<(), Error> {
269 if self.ptr.is_null() {
270 return Err(Error::from(E_POINTER));
271 }
272 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
273 let put_mode_fn = vtbl.put_AudioBeamMode.ok_or_else(|| Error::from(E_FAIL))?;
274 let hr = unsafe { put_mode_fn(self.ptr, audio_beam_mode) };
275 if hr.is_err() {
276 Err(Error::from_hresult(hr))
277 } else {
278 Ok(())
279 }
280 }
281
282 pub fn get_beam_angle(&self) -> Result<f32, Error> {
283 if self.ptr.is_null() {
284 return Err(Error::from(E_POINTER));
285 }
286 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
287 let get_angle_fn = vtbl.get_BeamAngle.ok_or_else(|| Error::from(E_FAIL))?;
288 let mut beam_angle: f32 = 0.0;
289 let hr = unsafe { get_angle_fn(self.ptr, &mut beam_angle) };
290 if hr.is_err() {
291 Err(Error::from_hresult(hr))
292 } else {
293 Ok(beam_angle)
294 }
295 }
296
297 pub fn put_beam_angle(&self, beam_angle: f32) -> Result<(), Error> {
298 if self.ptr.is_null() {
299 return Err(Error::from(E_POINTER));
300 }
301 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
302 let put_angle_fn = vtbl.put_BeamAngle.ok_or_else(|| Error::from(E_FAIL))?;
303 let hr = unsafe { put_angle_fn(self.ptr, beam_angle) };
304 if hr.is_err() {
305 Err(Error::from_hresult(hr))
306 } else {
307 Ok(())
308 }
309 }
310
311 pub fn get_beam_angle_confidence(&self) -> Result<f32, Error> {
312 if self.ptr.is_null() {
313 return Err(Error::from(E_POINTER));
314 }
315 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
316 let get_confidence_fn = vtbl
317 .get_BeamAngleConfidence
318 .ok_or_else(|| Error::from(E_FAIL))?;
319 let mut beam_angle_confidence: f32 = 0.0;
320 let hr = unsafe { get_confidence_fn(self.ptr, &mut beam_angle_confidence) };
321 if hr.is_err() {
322 Err(Error::from_hresult(hr))
323 } else {
324 Ok(beam_angle_confidence)
325 }
326 }
327 pub fn open_input_stream(&self) -> Result<IStream, Error> {
328 if self.ptr.is_null() {
329 return Err(Error::from(E_POINTER));
330 }
331 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
332 let open_stream_fn = vtbl.OpenInputStream.ok_or_else(|| Error::from(E_FAIL))?;
333 let mut stream: *mut IStream = ptr::null_mut();
334 let hr = unsafe { open_stream_fn(self.ptr, &mut stream) };
335 if hr.is_err() {
336 Err(Error::from_hresult(hr))
337 } else if stream.is_null() {
338 Err(Error::from(E_POINTER))
339 } else {
340 unsafe { Ok(IStream::from_raw(stream as *mut std::ffi::c_void)) }
344 }
345 }
346
347 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
348 if self.ptr.is_null() {
349 return Err(Error::from(E_POINTER));
350 }
351 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
352 let get_time_fn = vtbl.get_RelativeTime.ok_or_else(|| Error::from(E_FAIL))?;
353 let mut relative_time: TIMESPAN = 0;
354 let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
355 if hr.is_err() {
356 Err(Error::from_hresult(hr))
357 } else {
358 Ok(relative_time)
359 }
360 }
361}
362
363impl Drop for AudioBeam {
364 fn drop(&mut self) {
365 if !self.ptr.is_null() {
366 unsafe {
367 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
368 && let Some(release_fn) = vtbl.Release
369 {
370 release_fn(self.ptr);
371 }
372 }
373 self.ptr = ptr::null_mut();
374 }
375 }
376}
377
378pub struct AudioBeamList {
379 ptr: *mut IAudioBeamList,
380}
381
382impl AudioBeamList {
383 pub(crate) fn new(ptr: *mut IAudioBeamList) -> Self {
384 assert!(!ptr.is_null());
385 Self { ptr }
386 }
387
388 pub fn get_beam_count(&self) -> Result<UINT, Error> {
389 if self.ptr.is_null() {
390 return Err(Error::from(E_POINTER));
391 }
392 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
393 let get_count_fn = vtbl.get_BeamCount.ok_or_else(|| Error::from(E_FAIL))?;
394 let mut count: UINT = 0;
395 let hr = unsafe { get_count_fn(self.ptr, &mut count) };
396 if hr.is_err() {
397 Err(Error::from_hresult(hr))
398 } else {
399 Ok(count)
400 }
401 }
402
403 pub fn open_audio_beam(&self, index: UINT) -> Result<AudioBeam, Error> {
404 if self.ptr.is_null() {
405 return Err(Error::from(E_POINTER));
406 }
407 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
408 let open_beam_fn = vtbl.OpenAudioBeam.ok_or_else(|| Error::from(E_FAIL))?;
409 let mut audio_beam_ptr: *mut IAudioBeam = ptr::null_mut();
410 let hr = unsafe { open_beam_fn(self.ptr, index, &mut audio_beam_ptr) };
411 if hr.is_err() {
412 Err(Error::from_hresult(hr))
413 } else if audio_beam_ptr.is_null() {
414 Err(Error::from(E_POINTER))
415 } else {
416 Ok(AudioBeam::new(audio_beam_ptr))
417 }
418 }
419}
420
421impl Drop for AudioBeamList {
422 fn drop(&mut self) {
423 if !self.ptr.is_null() {
424 unsafe {
425 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
426 && let Some(release_fn) = vtbl.Release
427 {
428 release_fn(self.ptr);
429 }
430 }
431 self.ptr = ptr::null_mut();
432 }
433 }
434}
435
436pub struct AudioBeamFrameList {
437 ptr: *mut IAudioBeamFrameList,
438}
439
440impl AudioBeamFrameList {
441 pub(crate) fn new(ptr: *mut IAudioBeamFrameList) -> Self {
442 assert!(!ptr.is_null());
443 Self { ptr }
444 }
445
446 pub fn get_beam_count(&self) -> Result<UINT, Error> {
447 if self.ptr.is_null() {
448 return Err(Error::from(E_POINTER));
449 }
450 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
451 let get_count_fn = vtbl.get_BeamCount.ok_or_else(|| Error::from(E_FAIL))?;
452 let mut count: UINT = 0;
453 let hr = unsafe { get_count_fn(self.ptr, &mut count) };
454 if hr.is_err() {
455 Err(Error::from_hresult(hr))
456 } else {
457 Ok(count)
458 }
459 }
460
461 pub fn open_audio_beam_frame(&self, index: UINT) -> Result<AudioBeamFrame, Error> {
462 if self.ptr.is_null() {
463 return Err(Error::from(E_POINTER));
464 }
465 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
466 let open_frame_fn = vtbl.OpenAudioBeamFrame.ok_or_else(|| Error::from(E_FAIL))?;
467 let mut audio_beam_frame_ptr: *mut IAudioBeamFrame = ptr::null_mut();
468 let hr = unsafe { open_frame_fn(self.ptr, index, &mut audio_beam_frame_ptr) };
469 if hr.is_err() {
470 Err(Error::from_hresult(hr))
471 } else if audio_beam_frame_ptr.is_null() {
472 Err(Error::from(E_POINTER))
473 } else {
474 Ok(AudioBeamFrame::new(audio_beam_frame_ptr))
475 }
476 }
477}
478
479impl Drop for AudioBeamFrameList {
480 fn drop(&mut self) {
481 if !self.ptr.is_null() {
482 unsafe {
483 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
484 && let Some(release_fn) = vtbl.Release
485 {
486 release_fn(self.ptr);
487 }
488 }
489 self.ptr = ptr::null_mut();
490 }
491 }
492}
493
494pub struct AudioBeamFrame {
495 ptr: *mut IAudioBeamFrame,
496}
497
498impl AudioBeamFrame {
499 pub(crate) fn new(ptr: *mut IAudioBeamFrame) -> Self {
500 assert!(!ptr.is_null());
501 Self { ptr }
502 }
503
504 pub fn get_audio_source(&self) -> Result<AudioSource, Error> {
505 if self.ptr.is_null() {
506 return Err(Error::from(E_POINTER));
507 }
508 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
509 let get_source_fn = vtbl.get_AudioSource.ok_or_else(|| Error::from(E_FAIL))?;
510 let mut audio_source_ptr: *mut IAudioSource = ptr::null_mut();
511 let hr = unsafe { get_source_fn(self.ptr, &mut audio_source_ptr) };
512 if hr.is_err() {
513 Err(Error::from_hresult(hr))
514 } else if audio_source_ptr.is_null() {
515 Err(Error::from(E_POINTER))
516 } else {
517 Ok(AudioSource::new(audio_source_ptr))
518 }
519 }
520
521 pub fn get_duration(&self) -> Result<TIMESPAN, Error> {
522 if self.ptr.is_null() {
523 return Err(Error::from(E_POINTER));
524 }
525 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
526 let get_duration_fn = vtbl.get_Duration.ok_or_else(|| Error::from(E_FAIL))?;
527 let mut duration: TIMESPAN = 0;
528 let hr = unsafe { get_duration_fn(self.ptr, &mut duration) };
529 if hr.is_err() {
530 Err(Error::from_hresult(hr))
531 } else {
532 Ok(duration)
533 }
534 }
535
536 pub fn get_audio_beam(&self) -> Result<AudioBeam, Error> {
537 if self.ptr.is_null() {
538 return Err(Error::from(E_POINTER));
539 }
540 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
541 let get_beam_fn = vtbl.get_AudioBeam.ok_or_else(|| Error::from(E_FAIL))?;
542 let mut audio_beam_ptr: *mut IAudioBeam = ptr::null_mut();
543 let hr = unsafe { get_beam_fn(self.ptr, &mut audio_beam_ptr) };
544 if hr.is_err() {
545 Err(Error::from_hresult(hr))
546 } else if audio_beam_ptr.is_null() {
547 Err(Error::from(E_POINTER))
548 } else {
549 Ok(AudioBeam::new(audio_beam_ptr))
550 }
551 }
552
553 pub fn get_sub_frame_count(&self) -> Result<UINT, Error> {
554 if self.ptr.is_null() {
555 return Err(Error::from(E_POINTER));
556 }
557 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
558 let get_count_fn = vtbl.get_SubFrameCount.ok_or_else(|| Error::from(E_FAIL))?;
559 let mut count: UINT = 0;
560 let hr = unsafe { get_count_fn(self.ptr, &mut count) };
561 if hr.is_err() {
562 Err(Error::from_hresult(hr))
563 } else {
564 Ok(count)
565 }
566 }
567
568 pub fn get_sub_frame(&self, sub_frame_index: UINT) -> Result<AudioBeamSubFrame, Error> {
569 if self.ptr.is_null() {
570 return Err(Error::from(E_POINTER));
571 }
572 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
573 let get_sub_frame_fn = vtbl.GetSubFrame.ok_or_else(|| Error::from(E_FAIL))?;
574 let mut audio_beam_sub_frame_ptr: *mut IAudioBeamSubFrame = ptr::null_mut();
575 let hr =
576 unsafe { get_sub_frame_fn(self.ptr, sub_frame_index, &mut audio_beam_sub_frame_ptr) };
577 if hr.is_err() {
578 Err(Error::from_hresult(hr))
579 } else if audio_beam_sub_frame_ptr.is_null() {
580 Err(Error::from(E_POINTER))
581 } else {
582 Ok(AudioBeamSubFrame::new(audio_beam_sub_frame_ptr))
583 }
584 }
585
586 pub fn get_relative_time_start(&self) -> Result<TIMESPAN, Error> {
587 if self.ptr.is_null() {
588 return Err(Error::from(E_POINTER));
589 }
590 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
591 let get_time_fn = vtbl
592 .get_RelativeTimeStart
593 .ok_or_else(|| Error::from(E_FAIL))?;
594 let mut relative_time: TIMESPAN = 0;
595 let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
596 if hr.is_err() {
597 Err(Error::from_hresult(hr))
598 } else {
599 Ok(relative_time)
600 }
601 }
602}
603
604impl Drop for AudioBeamFrame {
605 fn drop(&mut self) {
606 if !self.ptr.is_null() {
607 unsafe {
608 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
609 && let Some(release_fn) = vtbl.Release
610 {
611 release_fn(self.ptr);
612 }
613 }
614 self.ptr = ptr::null_mut();
615 }
616 }
617}
618
619pub struct AudioBeamSubFrame {
620 ptr: *mut IAudioBeamSubFrame,
621}
622
623impl AudioBeamSubFrame {
624 pub(crate) fn new(ptr: *mut IAudioBeamSubFrame) -> Self {
625 assert!(!ptr.is_null());
626 Self { ptr }
627 }
628
629 pub fn get_frame_length_in_bytes(&self) -> Result<UINT, Error> {
630 if self.ptr.is_null() {
631 return Err(Error::from(E_POINTER));
632 }
633 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
634 let get_length_fn = vtbl
635 .get_FrameLengthInBytes
636 .ok_or_else(|| Error::from(E_FAIL))?;
637 let mut length: UINT = 0;
638 let hr = unsafe { get_length_fn(self.ptr, &mut length) };
639 if hr.is_err() {
640 Err(Error::from_hresult(hr))
641 } else {
642 Ok(length)
643 }
644 }
645
646 pub fn get_duration(&self) -> Result<TIMESPAN, Error> {
647 if self.ptr.is_null() {
648 return Err(Error::from(E_POINTER));
649 }
650 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
651 let get_duration_fn = vtbl.get_Duration.ok_or_else(|| Error::from(E_FAIL))?;
652 let mut duration: TIMESPAN = 0;
653 let hr = unsafe { get_duration_fn(self.ptr, &mut duration) };
654 if hr.is_err() {
655 Err(Error::from_hresult(hr))
656 } else {
657 Ok(duration)
658 }
659 }
660
661 pub fn get_beam_angle(&self) -> Result<f32, Error> {
662 if self.ptr.is_null() {
663 return Err(Error::from(E_POINTER));
664 }
665 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
666 let get_angle_fn = vtbl.get_BeamAngle.ok_or_else(|| Error::from(E_FAIL))?;
667 let mut beam_angle: f32 = 0.0;
668 let hr = unsafe { get_angle_fn(self.ptr, &mut beam_angle) };
669 if hr.is_err() {
670 Err(Error::from_hresult(hr))
671 } else {
672 Ok(beam_angle)
673 }
674 }
675
676 pub fn get_beam_angle_confidence(&self) -> Result<f32, Error> {
677 if self.ptr.is_null() {
678 return Err(Error::from(E_POINTER));
679 }
680 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
681 let get_confidence_fn = vtbl
682 .get_BeamAngleConfidence
683 .ok_or_else(|| Error::from(E_FAIL))?;
684 let mut beam_angle_confidence: f32 = 0.0;
685 let hr = unsafe { get_confidence_fn(self.ptr, &mut beam_angle_confidence) };
686 if hr.is_err() {
687 Err(Error::from_hresult(hr))
688 } else {
689 Ok(beam_angle_confidence)
690 }
691 }
692
693 pub fn get_audio_beam_mode(&self) -> Result<AudioBeamMode, Error> {
694 if self.ptr.is_null() {
695 return Err(Error::from(E_POINTER));
696 }
697 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
698 let get_mode_fn = vtbl.get_AudioBeamMode.ok_or_else(|| Error::from(E_FAIL))?;
699 let mut audio_beam_mode: AudioBeamMode = AudioBeamMode::Automatic; let hr = unsafe { get_mode_fn(self.ptr, &mut audio_beam_mode) };
701 if hr.is_err() {
702 Err(Error::from_hresult(hr))
703 } else {
704 Ok(audio_beam_mode)
705 }
706 }
707
708 pub fn get_audio_body_correlation_count(&self) -> Result<UINT, Error> {
709 if self.ptr.is_null() {
710 return Err(Error::from(E_POINTER));
711 }
712 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
713 let get_count_fn = vtbl
714 .get_AudioBodyCorrelationCount
715 .ok_or_else(|| Error::from(E_FAIL))?;
716 let mut count: UINT = 0;
717 let hr = unsafe { get_count_fn(self.ptr, &mut count) };
718 if hr.is_err() {
719 Err(Error::from_hresult(hr))
720 } else {
721 Ok(count)
722 }
723 }
724
725 pub fn get_audio_body_correlation(&self, index: UINT) -> Result<AudioBodyCorrelation, Error> {
726 if self.ptr.is_null() {
727 return Err(Error::from(E_POINTER));
728 }
729 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
730 let get_correlation_fn = vtbl
731 .GetAudioBodyCorrelation
732 .ok_or_else(|| Error::from(E_FAIL))?;
733 let mut audio_body_correlation: *mut IAudioBodyCorrelation = ptr::null_mut();
734 let hr = unsafe { get_correlation_fn(self.ptr, index, &mut audio_body_correlation) };
735 if hr.is_err() {
736 Err(Error::from_hresult(hr))
737 } else {
738 Ok(AudioBodyCorrelation::new(audio_body_correlation))
739 }
740 }
741
742 pub fn copy_frame_data_to_array(&self, buffer: &mut [u8]) -> Result<(), Error> {
743 if self.ptr.is_null() {
744 return Err(Error::from(E_POINTER));
745 }
746 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
747 let copy_data_fn = vtbl
748 .CopyFrameDataToArray
749 .ok_or_else(|| Error::from(E_FAIL))?;
750
751 let capacity = buffer.len() as UINT;
752 let buffer_ptr = buffer.as_mut_ptr() as *mut BYTE;
753
754 let hr = unsafe { copy_data_fn(self.ptr, capacity, buffer_ptr) };
755 if hr.is_err() {
756 Err(Error::from_hresult(hr))
757 } else {
758 Ok(())
759 }
760 }
761
762 pub fn access_underlying_buffer(&self) -> Result<&[u8], Error> {
763 if self.ptr.is_null() {
764 return Err(Error::from(E_POINTER));
765 }
766 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
767 let access_buffer_fn = vtbl
768 .AccessUnderlyingBuffer
769 .ok_or_else(|| Error::from(E_FAIL))?;
770
771 let mut capacity: UINT = 0;
772 let mut buffer: *mut BYTE = ptr::null_mut();
773 let hr = unsafe { access_buffer_fn(self.ptr, &mut capacity, &mut buffer) };
774
775 if hr.is_err() {
776 Err(Error::from_hresult(hr))
777 } else if buffer.is_null() || capacity == 0 {
778 Err(Error::from(E_POINTER))
779 } else {
780 let slice =
782 unsafe { std::slice::from_raw_parts(buffer as *const u8, capacity as usize) };
783 Ok(slice)
784 }
785 }
786
787 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
788 if self.ptr.is_null() {
789 return Err(Error::from(E_POINTER));
790 }
791 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
792 let get_time_fn = vtbl.get_RelativeTime.ok_or_else(|| Error::from(E_FAIL))?;
793 let mut relative_time: TIMESPAN = 0;
794 let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
795 if hr.is_err() {
796 Err(Error::from_hresult(hr))
797 } else {
798 Ok(relative_time)
799 }
800 }
801}
802
803impl Drop for AudioBeamSubFrame {
804 fn drop(&mut self) {
805 if !self.ptr.is_null() {
806 unsafe {
807 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
808 && let Some(release_fn) = vtbl.Release
809 {
810 release_fn(self.ptr);
811 }
812 }
813 self.ptr = ptr::null_mut();
814 }
815 }
816}
817
818pub struct AudioBodyCorrelation {
819 ptr: *mut IAudioBodyCorrelation,
820}
821
822impl AudioBodyCorrelation {
823 pub(crate) fn new(ptr: *mut IAudioBodyCorrelation) -> Self {
824 assert!(!ptr.is_null());
825 Self { ptr }
826 }
827
828 pub fn get_body_tracking_id(&self) -> Result<UINT64, Error> {
829 if self.ptr.is_null() {
830 return Err(Error::from(E_POINTER));
831 }
832 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
833 let get_body_id_fn = vtbl.get_BodyTrackingId.ok_or_else(|| Error::from(E_FAIL))?;
834 let mut body_tracking_id: UINT64 = 0;
835 let hr = unsafe { get_body_id_fn(self.ptr, &mut body_tracking_id) };
836 if hr.is_err() {
837 Err(Error::from_hresult(hr))
838 } else {
839 Ok(body_tracking_id)
840 }
841 }
842}
843
844impl Drop for AudioBodyCorrelation {
845 fn drop(&mut self) {
846 if !self.ptr.is_null() {
847 unsafe {
848 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
849 && let Some(release_fn) = vtbl.Release
850 {
851 release_fn(self.ptr);
852 }
853 }
854 self.ptr = ptr::null_mut();
855 }
856 }
857}
858
859pub struct AudioBeamFrameReference {
860 ptr: *mut IAudioBeamFrameReference,
861}
862
863impl AudioBeamFrameReference {
864 pub(crate) fn new(ptr: *mut IAudioBeamFrameReference) -> Self {
865 assert!(!ptr.is_null());
866 Self { ptr }
867 }
868
869 pub fn acquire_beam_frame(&self) -> Result<AudioBeamFrameList, Error> {
870 if self.ptr.is_null() {
871 return Err(Error::from(E_POINTER));
872 }
873 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
874 let acquire_frame_fn = vtbl.AcquireBeamFrames.ok_or_else(|| Error::from(E_FAIL))?;
875 let mut audio_beam_frame_list_ptr: *mut IAudioBeamFrameList = ptr::null_mut();
876 let hr = unsafe { acquire_frame_fn(self.ptr, &mut audio_beam_frame_list_ptr) };
877 if hr.is_err() {
878 Err(Error::from_hresult(hr))
879 } else if audio_beam_frame_list_ptr.is_null() {
880 Err(Error::from(E_POINTER))
881 } else {
882 Ok(AudioBeamFrameList::new(audio_beam_frame_list_ptr))
883 }
884 }
885
886 pub fn get_relative_time(&self) -> Result<TIMESPAN, Error> {
887 if self.ptr.is_null() {
888 return Err(Error::from(E_POINTER));
889 }
890 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
891 let get_time_fn = vtbl.get_RelativeTime.ok_or_else(|| Error::from(E_FAIL))?;
892 let mut relative_time: TIMESPAN = 0;
893 let hr = unsafe { get_time_fn(self.ptr, &mut relative_time) };
894 if hr.is_err() {
895 Err(Error::from_hresult(hr))
896 } else {
897 Ok(relative_time)
898 }
899 }
900}
901
902impl Drop for AudioBeamFrameReference {
903 fn drop(&mut self) {
904 if !self.ptr.is_null() {
905 unsafe {
906 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
907 && let Some(release_fn) = vtbl.Release
908 {
909 release_fn(self.ptr);
910 }
911 }
912 self.ptr = ptr::null_mut();
913 }
914 }
915}
916
917pub struct AudioBeamFrameArrivedEventArgs {
918 ptr: *mut IAudioBeamFrameArrivedEventArgs,
919}
920
921impl AudioBeamFrameArrivedEventArgs {
922 pub(crate) fn new(ptr: *mut IAudioBeamFrameArrivedEventArgs) -> Self {
923 assert!(!ptr.is_null());
924 Self { ptr }
925 }
926
927 pub fn get_frame_reference(&self) -> Result<AudioBeamFrameReference, Error> {
928 if self.ptr.is_null() {
929 return Err(Error::from(E_POINTER));
930 }
931 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
932 let get_frame_fn = vtbl.get_FrameReference.ok_or_else(|| Error::from(E_FAIL))?;
933 let mut audio_beam_frame_reference_ptr: *mut IAudioBeamFrameReference = ptr::null_mut();
934 let hr = unsafe { get_frame_fn(self.ptr, &mut audio_beam_frame_reference_ptr) };
935 if hr.is_err() {
936 Err(Error::from_hresult(hr))
937 } else if audio_beam_frame_reference_ptr.is_null() {
938 Err(Error::from(E_POINTER))
939 } else {
940 Ok(AudioBeamFrameReference::new(audio_beam_frame_reference_ptr))
941 }
942 }
943}
944
945impl Drop for AudioBeamFrameArrivedEventArgs {
946 fn drop(&mut self) {
947 if !self.ptr.is_null() {
948 unsafe {
949 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
950 && let Some(release_fn) = vtbl.Release
951 {
952 release_fn(self.ptr);
953 }
954 }
955 self.ptr = ptr::null_mut();
956 }
957 }
958}
959
960pub struct AudioBeamFrameReader {
961 ptr: *mut IAudioBeamFrameReader,
962}
963
964impl AudioBeamFrameReader {
965 pub(crate) fn new(ptr: *mut IAudioBeamFrameReader) -> Self {
966 assert!(!ptr.is_null());
967 Self { ptr }
968 }
969
970 pub fn subscribe_frame_arrived(&self) -> Result<WAITABLE_HANDLE, Error> {
971 if self.ptr.is_null() {
972 return Err(Error::from(E_POINTER));
973 }
974 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
975 let subscribe_fn = vtbl
976 .SubscribeFrameArrived
977 .ok_or_else(|| Error::from(E_FAIL))?;
978 let mut waitable_handle: WAITABLE_HANDLE = HANDLE::default();
979 let hr = unsafe { subscribe_fn(self.ptr, &mut waitable_handle) };
980 if hr.is_err() {
981 Err(Error::from_hresult(hr))
982 } else {
983 Ok(waitable_handle)
984 }
985 }
986
987 pub fn unsubscribe_frame_arrived(&self, waitable_handle: WAITABLE_HANDLE) -> Result<(), Error> {
988 if self.ptr.is_null() {
989 return Err(Error::from(E_POINTER));
990 }
991 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
992 let unsubscribe_fn = vtbl
993 .UnsubscribeFrameArrived
994 .ok_or_else(|| Error::from(E_FAIL))?;
995 let hr = unsafe { unsubscribe_fn(self.ptr, waitable_handle) };
996 if hr.is_err() {
997 Err(Error::from_hresult(hr))
998 } else {
999 Ok(())
1000 }
1001 }
1002
1003 pub fn get_frame_arrived_event_data(
1004 &self,
1005 waitable_handle: WAITABLE_HANDLE,
1006 ) -> Result<AudioBeamFrameArrivedEventArgs, Error> {
1007 if self.ptr.is_null() {
1008 return Err(Error::from(E_POINTER));
1009 }
1010 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
1011 let get_data_fn = vtbl
1012 .GetFrameArrivedEventData
1013 .ok_or_else(|| Error::from(E_FAIL))?;
1014 let mut event_data: *mut IAudioBeamFrameArrivedEventArgs = ptr::null_mut();
1015 let hr = unsafe { get_data_fn(self.ptr, waitable_handle, &mut event_data) };
1016 if hr.is_err() {
1017 Err(Error::from_hresult(hr))
1018 } else {
1019 Ok(AudioBeamFrameArrivedEventArgs::new(event_data))
1020 }
1021 }
1022
1023 pub fn acquire_latest_beam_frames(&self) -> Result<AudioBeamFrameList, Error> {
1024 if self.ptr.is_null() {
1025 return Err(Error::from(E_POINTER));
1026 }
1027 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
1028 let acquire_fn = vtbl
1029 .AcquireLatestBeamFrames
1030 .ok_or_else(|| Error::from(E_FAIL))?;
1031 let mut audio_beam_frame_list_ptr: *mut IAudioBeamFrameList = ptr::null_mut();
1032 let hr = unsafe { acquire_fn(self.ptr, &mut audio_beam_frame_list_ptr) };
1033 if hr.is_err() {
1034 Err(Error::from_hresult(hr))
1035 } else if audio_beam_frame_list_ptr.is_null() {
1036 Err(Error::from(E_POINTER))
1037 } else {
1038 Ok(AudioBeamFrameList::new(audio_beam_frame_list_ptr))
1039 }
1040 }
1041
1042 pub fn get_is_paused(&self) -> Result<bool, Error> {
1043 if self.ptr.is_null() {
1044 return Err(Error::from(E_POINTER));
1045 }
1046 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
1047 let get_paused_fn = vtbl.get_IsPaused.ok_or_else(|| Error::from(E_FAIL))?;
1048 let mut is_paused: BOOLEAN = 0;
1049 let hr = unsafe { get_paused_fn(self.ptr, &mut is_paused) };
1050 if hr.is_err() {
1051 Err(Error::from_hresult(hr))
1052 } else {
1053 Ok(is_paused != 0)
1054 }
1055 }
1056
1057 pub fn put_is_paused(&self, is_paused: bool) -> Result<(), Error> {
1058 if self.ptr.is_null() {
1059 return Err(Error::from(E_POINTER));
1060 }
1061 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
1062 let put_paused_fn = vtbl.put_IsPaused.ok_or_else(|| Error::from(E_FAIL))?;
1063 let paused_value: BOOLEAN = if is_paused { 1 } else { 0 };
1064 let hr = unsafe { put_paused_fn(self.ptr, paused_value) };
1065 if hr.is_err() {
1066 Err(Error::from_hresult(hr))
1067 } else {
1068 Ok(())
1069 }
1070 }
1071
1072 pub fn get_audio_source(&self) -> Result<AudioSource, Error> {
1073 if self.ptr.is_null() {
1074 return Err(Error::from(E_POINTER));
1075 }
1076 let vtbl = unsafe { (*self.ptr).lpVtbl.as_ref() }.ok_or_else(|| Error::from(E_POINTER))?;
1077 let get_source_fn = vtbl.get_AudioSource.ok_or_else(|| Error::from(E_FAIL))?;
1078 let mut audio_source_ptr: *mut IAudioSource = ptr::null_mut();
1079 let hr = unsafe { get_source_fn(self.ptr, &mut audio_source_ptr) };
1080 if hr.is_err() {
1081 Err(Error::from_hresult(hr))
1082 } else if audio_source_ptr.is_null() {
1083 Err(Error::from(E_POINTER))
1084 } else {
1085 Ok(AudioSource::new(audio_source_ptr))
1086 }
1087 }
1088}
1089
1090impl Drop for AudioBeamFrameReader {
1091 fn drop(&mut self) {
1092 if !self.ptr.is_null() {
1093 unsafe {
1094 if let Some(vtbl) = (*self.ptr).lpVtbl.as_ref()
1095 && let Some(release_fn) = vtbl.Release
1096 {
1097 release_fn(self.ptr);
1098 }
1099 }
1100 self.ptr = ptr::null_mut();
1101 }
1102 }
1103}
1104
1105#[cfg(test)]
1107mod tests {
1108 use std::{thread, time::Duration};
1109
1110 use crate::{DEFAULT_FRAME_WAIT_TIMEOUT_MS, kinect};
1111
1112 use windows::Win32::{
1113 Foundation::{WAIT_OBJECT_0, WAIT_TIMEOUT},
1114 System::{Com::Urlmon::E_PENDING, Threading::WaitForSingleObject},
1115 };
1116
1117 #[test]
1118 fn get_latest_audio_frame() -> anyhow::Result<()> {
1119 let kinect = kinect::get_default_kinect_sensor()?;
1120 kinect.open()?;
1121 let audio_source = kinect.audio_source()?;
1122 let audio_beam_frame_reader = audio_source.open_reader()?;
1123
1124 let mut frame_counter = 0;
1125 loop {
1126 match audio_beam_frame_reader.acquire_latest_beam_frames() {
1127 Ok(frame_list) => {
1128 let beam_count = frame_list.get_beam_count()?;
1129 assert_eq!(beam_count, 1, "Expected only 1 audio beam");
1130
1131 let audio_beam_frame = frame_list.open_audio_beam_frame(0)?;
1132 let duration = audio_beam_frame.get_duration()?;
1133 let sub_frame_count = audio_beam_frame.get_sub_frame_count()?;
1134 let audio_beam = audio_beam_frame.get_audio_beam()?;
1135 let beam_angle = audio_beam.get_beam_angle()?;
1136 let beam_angle_confidence = audio_beam.get_beam_angle_confidence()?;
1137 let relative_time = audio_beam.get_relative_time()?;
1138
1139 println!(
1140 "AudioFrame Duration: {duration}, SubFrameCount:{sub_frame_count}, Beam Angle: {beam_angle}, Confidence: {beam_angle_confidence}, Relative Time: {relative_time}"
1141 );
1142
1143 assert!(
1144 sub_frame_count >= 1,
1145 "Expected at least 1 sub-frame in audio beam frame"
1146 );
1147 assert!(
1148 (-180.0..=180.0).contains(&beam_angle),
1149 "Beam angle out of range"
1150 );
1151 assert!(
1152 (0.0..=1.0).contains(&beam_angle_confidence),
1153 "Beam angle confidence out of range"
1154 );
1155 assert!(relative_time >= 0, "Relative time should be non-negative");
1156
1157 frame_counter += 1;
1158 if frame_counter >= 10 {
1159 break; }
1161 }
1162 Err(e) => {
1163 if e.code() == E_PENDING {
1164 println!("Audio frame not ready yet, waiting...");
1165 thread::sleep(Duration::from_millis(100));
1167 } else {
1168 return Err(anyhow::Error::new(e));
1170 }
1171 }
1172 }
1173 }
1174
1175 Ok(())
1176 }
1177
1178 #[test]
1179 fn subscribe_audio_frame_arrived_event() -> anyhow::Result<()> {
1180 let kinect = kinect::get_default_kinect_sensor()?;
1181 kinect.open()?;
1182 let audio_source = kinect.audio_source()?;
1183 let audio_frame_reader = audio_source.open_reader()?;
1184 let waitable_handle = audio_frame_reader.subscribe_frame_arrived()?;
1185 let is_active = audio_source.get_is_active()?;
1186 assert!(is_active, "Audio source should be active");
1187
1188 let mut frame_counter = 0;
1189 loop {
1190 let wait_result =
1191 unsafe { WaitForSingleObject(waitable_handle, DEFAULT_FRAME_WAIT_TIMEOUT_MS) };
1192 if WAIT_OBJECT_0 == wait_result {
1193 let event_args =
1194 audio_frame_reader.get_frame_arrived_event_data(waitable_handle)?;
1195
1196 let frame_reference = event_args.get_frame_reference()?;
1197 let frame_list = frame_reference.acquire_beam_frame()?;
1198 let beam_count = frame_list.get_beam_count()?;
1199 assert_eq!(beam_count, 1, "Expected only 1 audio beam");
1200
1201 let audio_beam_frame = frame_list.open_audio_beam_frame(0)?;
1202 let duration = audio_beam_frame.get_duration()?;
1203 let sub_frame_count = audio_beam_frame.get_sub_frame_count()?;
1204 let audio_beam = audio_beam_frame.get_audio_beam()?;
1205 let beam_mode = audio_beam.get_audio_beam_mode()?;
1206 let beam_angle = audio_beam.get_beam_angle()?;
1207 let beam_angle_confidence = audio_beam.get_beam_angle_confidence()?;
1208 let relative_time = audio_beam.get_relative_time()?;
1209
1210 println!(
1211 "AudioFrame Duration ticks: {duration}, SubFrameCount:{sub_frame_count}, Beam Mode: {beam_mode:?}, Beam Angle: {beam_angle}, Confidence: {beam_angle_confidence}, Relative Time: {relative_time}"
1212 );
1213
1214 assert!(
1215 sub_frame_count >= 1,
1216 "Expected at least 1 sub-frame in audio beam frame"
1217 );
1218 assert!(
1219 (-180.0..=180.0).contains(&beam_angle),
1220 "Beam angle out of range"
1221 );
1222 assert!(
1223 (0.0..=1.0).contains(&beam_angle_confidence),
1224 "Beam angle confidence out of range"
1225 );
1226 assert!(relative_time >= 0, "Relative time should be non-negative");
1227
1228 for i in 0..sub_frame_count {
1229 let sub_frame = audio_beam_frame.get_sub_frame(i)?;
1230 let sub_frame_duration = sub_frame.get_duration()?;
1231 assert!(
1232 sub_frame_duration > 0,
1233 "Sub-frame duration should be positive"
1234 );
1235
1236 let sub_frame_bytes = sub_frame.get_frame_length_in_bytes()?;
1237 assert!(
1238 sub_frame_bytes > 0,
1239 "Sub-frame length in bytes should be positive"
1240 );
1241
1242 let sub_frame_data = sub_frame.access_underlying_buffer()?;
1243 assert!(
1244 !sub_frame_data.is_empty(),
1245 "Sub-frame data should not be empty"
1246 );
1247 println!(
1248 "SubFrame {}: Duration ticks: {}, Length: {}, Data Size: {} bytes",
1249 i,
1250 sub_frame_duration,
1251 sub_frame_bytes,
1252 sub_frame_data.len()
1253 );
1254 }
1255
1256 frame_counter += 1;
1257 if frame_counter >= 10 {
1258 break; }
1260 } else if WAIT_TIMEOUT == wait_result {
1261 println!("No new audio frame available, waiting...");
1262 } else {
1263 return Err(anyhow::anyhow!(
1264 "WaitForSingleObject failed with result: {:?}",
1265 wait_result
1266 ));
1267 }
1268 }
1269
1270 audio_frame_reader.unsubscribe_frame_arrived(waitable_handle)?;
1272
1273 Ok(())
1274 }
1275}