ref_app_breathing.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2023-2024
2 // All rights reserved
3 // This file is subject to the terms and conditions defined in the file
4 // 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
5 // of this source code package.
6
7 #include <complex.h>
8 #include <math.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 #include "acc_alg_basic_utils.h"
13 #include "acc_algorithm.h"
14 #include "acc_detector_presence.h"
15 #include "acc_integration.h"
16 #include "ref_app_breathing.h"
17
18 #define B_STATIC_LENGTH (3U)
19 #define A_STATIC_LENGTH (2U)
20 #define B_ANGLE_LENGTH (5U)
21 #define A_ANGLE_LENGTH (4U)
22
23 struct ref_app_breathing_handle
24 {
25 acc_detector_presence_handle_t *presence_handle;
26
27 float start_m;
28 float step_length_m;
29 int32_t start_point;
30 uint16_t num_points_to_analyze_half_width;
31 uint16_t num_points_to_analyze;
32 uint16_t end_point;
33 float frame_rate;
34 float lowest_freq;
35 float highest_freq;
36 uint16_t use_presence_processor;
37 uint16_t distance_determination_count;
38 uint16_t time_series_length_s;
39 uint16_t time_series_length;
40 uint16_t padded_time_series_length_shift;
41 uint16_t padded_time_series_length;
42 uint16_t num_points;
43 uint16_t sweeps_per_frame;
44 float intra_detection_threshold;
45
46 ref_app_breathing_app_state_t app_state;
47 ref_app_breathing_app_state_t prev_app_state;
48
49 float presence_sf;
50 float breathing_sf;
51
52 float b_static[B_STATIC_LENGTH];
53 float a_static[A_STATIC_LENGTH];
54 float b_angle[B_ANGLE_LENGTH];
55 float a_angle[A_ANGLE_LENGTH];
56
57 float complex *mean_sweep;
58 float complex *sparse_iq_buffer;
59 float complex *filt_sparse_iq_buffer;
60 float complex *filt_sparse_iq;
61 float *angle;
62 float *prev_angle;
63 float *lp_filt_ampl;
64 float *unwrapped_angle;
65 float *angle_buffer;
66 float *filt_angle_buffer;
67 float *breathing_motion_buffer;
68 float *hamming_window;
69 float *windowed_breathing_motion_buffer;
70 float complex *rfft_output;
71 uint16_t rfft_output_length;
72 float *weighted_psd;
73 float freq_delta;
74
75 uint16_t distance_determination_counter;
76 bool presence_init;
77 float presence_distance;
78 bool base_presence_dist;
79 float base_presence_distance;
80 float presence_distance_threshold;
81 bool first;
82 uint16_t init_count;
83 uint16_t count;
84 bool initialized;
85 uint16_t count_limit;
86 };
87
88 static bool validate_config(ref_app_breathing_config_t *config);
89
90 static void determine_state(ref_app_breathing_handle_t *handle, acc_detector_presence_result_t *presence_result);
91
92 static void update_presence_distance(ref_app_breathing_handle_t *handle, float presence_distance);
93
94 static bool reinit_breathing(ref_app_breathing_handle_t *handle, uint16_t start_point, uint16_t end_point);
95
96 static bool perform_action_based_on_state(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result);
97
98 static bool process_breathing(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result);
99
100 ref_app_breathing_config_t *ref_app_breathing_config_create(void)
101 {
102 ref_app_breathing_config_t *config = acc_integration_mem_alloc(sizeof(*config));
103
104 if (config != NULL)
105 {
106 config->presence_config = acc_detector_presence_config_create();
107
108 if (config->presence_config == NULL)
109 {
110 ref_app_breathing_config_destroy(config);
111 return NULL;
112 }
113
114 config->time_series_length_s = 20U;
115 config->lowest_breathing_rate = 6U;
116 config->highest_breathing_rate = 60U;
117 config->num_dists_to_analyze = 3U;
118 config->use_presence_processor = true;
119 config->distance_determination_duration_s = 5U;
120
121 acc_detector_presence_config_t *presence_config = config->presence_config;
122
123 acc_detector_presence_config_start_set(presence_config, 0.3f);
124 acc_detector_presence_config_end_set(presence_config, 1.5f);
125 acc_detector_presence_config_hwaas_set(presence_config, 32U);
126 acc_detector_presence_config_frame_rate_set(presence_config, 10.0f);
127 acc_detector_presence_config_sweeps_per_frame_set(presence_config, 16U);
128 acc_detector_presence_config_auto_profile_set(presence_config, false);
129 acc_detector_presence_config_profile_set(presence_config, ACC_CONFIG_PROFILE_3);
130 acc_detector_presence_config_auto_step_length_set(presence_config, false);
131 acc_detector_presence_config_step_length_set(presence_config, 24U);
132 acc_detector_presence_config_automatic_subsweeps_set(presence_config, false);
133 acc_detector_presence_config_inter_frame_presence_timeout_set(presence_config, 0U);
134 acc_detector_presence_config_inter_frame_fast_cutoff_set(presence_config, 20.0f);
135 acc_detector_presence_config_intra_detection_threshold_set(presence_config, 6.0f);
136 acc_detector_presence_config_intra_output_time_const_set(presence_config, 0.5f);
137 acc_detector_presence_config_inter_output_time_const_set(presence_config, 5.0f);
138 }
139
140 return config;
141 }
142
143 void ref_app_breathing_config_destroy(ref_app_breathing_config_t *config)
144 {
145 if (config != NULL)
146 {
147 if (config->presence_config != NULL)
148 {
149 acc_detector_presence_config_destroy(config->presence_config);
150 }
151
152 acc_integration_mem_free(config);
153 }
154 }
155
156 ref_app_breathing_handle_t *ref_app_breathing_create(ref_app_breathing_config_t *config)
157 {
158 if (!validate_config(config))
159 {
160 return NULL;
161 }
162
163 ref_app_breathing_handle_t *handle = acc_integration_mem_calloc(1, sizeof(*handle));
164
165 if (handle != NULL)
166 {
167 handle->frame_rate = acc_detector_presence_config_frame_rate_get(config->presence_config);
168 handle->sweeps_per_frame = acc_detector_presence_config_sweeps_per_frame_get(config->presence_config);
169 handle->intra_detection_threshold = acc_detector_presence_config_intra_detection_threshold_get(config->presence_config);
170
171 acc_detector_presence_metadata_t presence_metadata;
172
173 handle->presence_handle = acc_detector_presence_create(config->presence_config, &presence_metadata);
174
175 if (handle->presence_handle == NULL)
176 {
177 ref_app_breathing_destroy(handle);
178 return NULL;
179 }
180
181 handle->start_m = presence_metadata.start_m;
182 handle->step_length_m = presence_metadata.step_length_m;
183 handle->num_points = presence_metadata.num_points;
184
185 handle->lowest_freq = (float)config->lowest_breathing_rate / 60.0f;
186 handle->highest_freq = (float)config->highest_breathing_rate / 60.0f;
187 handle->use_presence_processor = config->use_presence_processor;
188 handle->time_series_length_s = config->time_series_length_s;
189 handle->distance_determination_count = config->distance_determination_duration_s * handle->frame_rate;
190 handle->num_points_to_analyze_half_width = config->num_dists_to_analyze / 2U;
191 handle->num_points_to_analyze = config->use_presence_processor ? handle->num_points_to_analyze_half_width * 2U + 1U : handle->num_points;
192
193 handle->time_series_length = handle->time_series_length_s * handle->frame_rate;
194 handle->padded_time_series_length_shift = 0U;
195 handle->padded_time_series_length = 1U << handle->padded_time_series_length_shift;
196
197 while (handle->padded_time_series_length < handle->time_series_length)
198 {
199 handle->padded_time_series_length_shift++;
200 handle->padded_time_series_length = 1U << handle->padded_time_series_length_shift;
201 }
202
203 handle->rfft_output_length = (handle->padded_time_series_length / 2U) + 1U;
204 handle->distance_determination_counter = 0U;
205 handle->presence_init = false;
206 handle->presence_distance = 0.0f;
207 handle->base_presence_dist = false;
208 handle->base_presence_distance = 0.0f;
209 handle->presence_distance_threshold = acc_algorithm_get_fwhm(acc_detector_presence_config_profile_get(config->presence_config)) * 2.0f;
210 handle->first = true;
211 handle->init_count = 0U;
212 handle->count = 0U;
213 handle->initialized = false;
214 handle->presence_sf = acc_algorithm_exp_smoothing_coefficient(handle->frame_rate, (float)config->distance_determination_duration_s / 4.0f);
215 handle->breathing_sf = acc_algorithm_exp_smoothing_coefficient(handle->frame_rate, handle->time_series_length_s / 2.0f);
216
217 handle->app_state = REF_APP_BREATHING_APP_STATE_INIT;
218 handle->prev_app_state = REF_APP_BREATHING_APP_STATE_INIT;
219
220 handle->count_limit = handle->time_series_length / 2U;
221
222 acc_algorithm_butter_lowpass(handle->lowest_freq, handle->frame_rate, handle->b_static, handle->a_static);
223 acc_algorithm_butter_bandpass(handle->lowest_freq, handle->highest_freq, handle->frame_rate, handle->b_angle, handle->a_angle);
224
225 handle->mean_sweep = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->mean_sweep));
226 handle->filt_sparse_iq = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->filt_sparse_iq));
227 handle->sparse_iq_buffer = acc_integration_mem_alloc(B_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->sparse_iq_buffer));
228 handle->filt_sparse_iq_buffer =
229 acc_integration_mem_alloc(A_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_sparse_iq_buffer));
230 handle->angle = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->angle));
231 handle->prev_angle = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->prev_angle));
232 handle->lp_filt_ampl = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->lp_filt_ampl));
233 handle->unwrapped_angle = acc_integration_mem_alloc(handle->num_points_to_analyze * sizeof(*handle->unwrapped_angle));
234 handle->angle_buffer = acc_integration_mem_alloc(B_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->angle_buffer));
235 handle->filt_angle_buffer = acc_integration_mem_alloc(A_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_angle_buffer));
236 handle->breathing_motion_buffer =
237 acc_integration_mem_alloc(handle->time_series_length * handle->num_points_to_analyze * sizeof(*handle->breathing_motion_buffer));
238 handle->hamming_window = acc_integration_mem_alloc(handle->time_series_length * sizeof(*handle->hamming_window));
239 handle->windowed_breathing_motion_buffer =
240 acc_integration_mem_alloc(handle->time_series_length * handle->num_points_to_analyze * sizeof(*handle->windowed_breathing_motion_buffer));
241 handle->rfft_output = acc_integration_mem_alloc(handle->rfft_output_length * handle->num_points_to_analyze * sizeof(*handle->rfft_output));
242 handle->weighted_psd = acc_integration_mem_alloc(handle->rfft_output_length * sizeof(*handle->weighted_psd));
243
244 bool status = handle->mean_sweep != NULL && handle->filt_sparse_iq != NULL && handle->sparse_iq_buffer != NULL &&
245 handle->filt_sparse_iq_buffer != NULL && handle->angle != NULL && handle->prev_angle != NULL && handle->lp_filt_ampl != NULL &&
246 handle->unwrapped_angle != NULL && handle->angle_buffer != NULL && handle->filt_angle_buffer != NULL &&
247 handle->breathing_motion_buffer != NULL && handle->hamming_window != NULL && handle->windowed_breathing_motion_buffer != NULL &&
248 handle->rfft_output != NULL && handle->weighted_psd != NULL;
249
250 if (status)
251 {
252 handle->freq_delta = acc_algorithm_fftfreq_delta(handle->padded_time_series_length, 1.0f / handle->frame_rate);
253 acc_algorithm_hamming(handle->time_series_length, handle->hamming_window);
254 }
255 else
256 {
257 ref_app_breathing_destroy(handle);
258 return NULL;
259 }
260 }
261
262 return handle;
263 }
264
265 void ref_app_breathing_destroy(ref_app_breathing_handle_t *handle)
266 {
267 if (handle != NULL)
268 {
269 if (handle->presence_handle != NULL)
270 {
271 acc_detector_presence_destroy(handle->presence_handle);
272 }
273
274 if (handle->mean_sweep != NULL)
275 {
276 acc_integration_mem_free(handle->mean_sweep);
277 }
278
279 if (handle->filt_sparse_iq != NULL)
280 {
281 acc_integration_mem_free(handle->filt_sparse_iq);
282 }
283
284 if (handle->sparse_iq_buffer != NULL)
285 {
286 acc_integration_mem_free(handle->sparse_iq_buffer);
287 }
288
289 if (handle->filt_sparse_iq_buffer != NULL)
290 {
291 acc_integration_mem_free(handle->filt_sparse_iq_buffer);
292 }
293
294 if (handle->angle != NULL)
295 {
296 acc_integration_mem_free(handle->angle);
297 }
298
299 if (handle->prev_angle != NULL)
300 {
301 acc_integration_mem_free(handle->prev_angle);
302 }
303
304 if (handle->lp_filt_ampl != NULL)
305 {
306 acc_integration_mem_free(handle->lp_filt_ampl);
307 }
308
309 if (handle->unwrapped_angle != NULL)
310 {
311 acc_integration_mem_free(handle->unwrapped_angle);
312 }
313
314 if (handle->angle_buffer != NULL)
315 {
316 acc_integration_mem_free(handle->angle_buffer);
317 }
318
319 if (handle->filt_angle_buffer != NULL)
320 {
321 acc_integration_mem_free(handle->filt_angle_buffer);
322 }
323
324 if (handle->breathing_motion_buffer != NULL)
325 {
326 acc_integration_mem_free(handle->breathing_motion_buffer);
327 }
328
329 if (handle->hamming_window != NULL)
330 {
331 acc_integration_mem_free(handle->hamming_window);
332 }
333
334 if (handle->windowed_breathing_motion_buffer != NULL)
335 {
336 acc_integration_mem_free(handle->windowed_breathing_motion_buffer);
337 }
338
339 if (handle->rfft_output != NULL)
340 {
341 acc_integration_mem_free(handle->rfft_output);
342 }
343
344 if (handle->weighted_psd != NULL)
345 {
346 acc_integration_mem_free(handle->weighted_psd);
347 }
348
349 acc_integration_mem_free(handle);
350 }
351 }
352
353 bool ref_app_breathing_get_buffer_size(ref_app_breathing_handle_t *handle, uint32_t *buffer_size)
354 {
355 return acc_detector_presence_get_buffer_size(handle->presence_handle, buffer_size);
356 }
357
358 bool ref_app_breathing_prepare(ref_app_breathing_handle_t *handle,
359 ref_app_breathing_config_t *config,
360 acc_sensor_t *sensor,
361 const acc_cal_result_t *sensor_cal_result,
362 void *buffer,
363 uint32_t buffer_size)
364 {
365 return acc_detector_presence_prepare(handle->presence_handle, config->presence_config, sensor, sensor_cal_result, buffer, buffer_size);
366 }
367
368 bool ref_app_breathing_process(ref_app_breathing_handle_t *handle, void *buffer, ref_app_breathing_result_t *result)
369 {
370 bool status = acc_detector_presence_process(handle->presence_handle, buffer, &result->presence_result);
371
372 if (status)
373 {
374 if (result->presence_result.processing_result.calibration_needed)
375 {
376 handle->base_presence_dist = false;
377 handle->base_presence_distance = 0.0f;
378 }
379 else
380 {
381 determine_state(handle, &result->presence_result);
382
383 update_presence_distance(handle, result->presence_result.presence_distance);
384
385 status = perform_action_based_on_state(handle, result->presence_result.processing_result.frame, result);
386 }
387 }
388
389 if (status)
390 {
391 result->app_state = handle->app_state;
392
393 handle->prev_app_state = handle->app_state;
394 }
395
396 return status;
397 }
398
399 static bool validate_config(ref_app_breathing_config_t *config)
400 {
401 float frame_rate = acc_detector_presence_config_frame_rate_get(config->presence_config);
402
403 bool status = true;
404
405 if (frame_rate == 0.0f)
406 {
407 printf("Frame rate must be set, i.e. > 0.0\n");
408 status = false;
409 }
410
411 if (config->lowest_breathing_rate >= config->highest_breathing_rate)
412 {
413 printf("Lowest breathing rate must be lower than highest breathing rate\n");
414 status = false;
415 }
416
417 if (config->num_dists_to_analyze < 1U)
418 {
419 printf("Number of distances to analyze must be higher than 1");
420 status = false;
421 }
422
423 return status;
424 }
425
426 static void determine_state(ref_app_breathing_handle_t *handle, acc_detector_presence_result_t *presence_result)
427 {
428 if (!presence_result->presence_detected)
429 {
430 handle->app_state = REF_APP_BREATHING_APP_STATE_NO_PRESENCE;
431 }
432 else if (handle->intra_detection_threshold < presence_result->intra_presence_score)
433 {
434 handle->app_state = REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE;
435 }
436 else if (!handle->base_presence_dist && handle->use_presence_processor)
437 {
438 handle->app_state = REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE;
439 }
440 else if (!handle->use_presence_processor || handle->distance_determination_count <= handle->distance_determination_counter)
441 {
442 handle->app_state = REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE;
443 }
444 else
445 {
446 // Do nothing
447 }
448 }
449
450 static void update_presence_distance(ref_app_breathing_handle_t *handle, float presence_distance)
451 {
452 if (!handle->presence_init)
453 {
454 handle->presence_init = true;
455 handle->presence_distance = presence_distance;
456 }
457
458 handle->presence_distance = handle->presence_distance * handle->presence_sf + presence_distance * (1.0f - handle->presence_sf);
459
460 if (handle->base_presence_dist && handle->presence_distance_threshold < fabsf(handle->base_presence_distance - handle->presence_distance))
461 {
462 handle->base_presence_dist = false;
463 handle->base_presence_distance = 0.0f;
464 }
465 }
466
467 static bool reinit_breathing(ref_app_breathing_handle_t *handle, uint16_t start_point, uint16_t end_point)
468 {
469 handle->start_point = start_point;
470 handle->end_point = end_point;
471 handle->num_points_to_analyze = end_point - start_point;
472
473 handle->first = true;
474 handle->init_count = 0U;
475 handle->count = 0U;
476 handle->initialized = false;
477
478 memset(handle->sparse_iq_buffer, 0, B_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->sparse_iq_buffer));
479 memset(handle->filt_sparse_iq_buffer, 0, A_STATIC_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_sparse_iq_buffer));
480 memset(handle->prev_angle, 0, handle->num_points_to_analyze * sizeof(*handle->prev_angle));
481 memset(handle->lp_filt_ampl, 0, handle->num_points_to_analyze * sizeof(*handle->lp_filt_ampl));
482 memset(handle->unwrapped_angle, 0, handle->num_points_to_analyze * sizeof(*handle->unwrapped_angle));
483 memset(handle->angle_buffer, 0, B_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->angle_buffer));
484 memset(handle->filt_angle_buffer, 0, A_ANGLE_LENGTH * handle->num_points_to_analyze * sizeof(*handle->filt_angle_buffer));
485 memset(handle->breathing_motion_buffer, 0, handle->time_series_length * handle->num_points_to_analyze * sizeof(*handle->breathing_motion_buffer));
486
487 return true;
488 }
489
490 static bool perform_action_based_on_state(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result)
491 {
492 bool status = true;
493
494 result->result_ready = false;
495
496 switch (handle->app_state)
497 {
498 case REF_APP_BREATHING_APP_STATE_INIT:
499 // Do nothing
500 break;
501 // No presence and intra presence require the same action
502 case REF_APP_BREATHING_APP_STATE_NO_PRESENCE:
503 case REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE:
504 handle->base_presence_dist = false;
505 handle->base_presence_distance = 0.0f;
506 break;
507 case REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE:
508 if (handle->app_state != handle->prev_app_state)
509 {
510 handle->distance_determination_counter = 0U;
511 }
512 else
513 {
514 handle->distance_determination_counter++;
515 handle->base_presence_dist = true;
516 handle->base_presence_distance = handle->presence_distance;
517 }
518
519 break;
520 case REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE:
521 if (handle->app_state != handle->prev_app_state)
522 {
523 uint16_t start_p;
524 uint16_t end_p;
525
526 if (handle->use_presence_processor)
527 {
528 uint16_t center_idx = (uint16_t)(((handle->base_presence_distance - handle->start_m) / handle->step_length_m) + 0.5f);
529 start_p = center_idx >= handle->num_points_to_analyze_half_width
530 ? (uint16_t)(center_idx - handle->num_points_to_analyze_half_width)
531 : 0U;
532 end_p = (center_idx + handle->num_points_to_analyze_half_width + 1U) <= handle->num_points
533 ? (center_idx + handle->num_points_to_analyze_half_width + 1U)
534 : handle->num_points;
535 }
536 else
537 {
538 start_p = 0U;
539 end_p = handle->num_points;
540 }
541
542 reinit_breathing(handle, start_p, end_p);
543 }
544
545 status = process_breathing(handle, frame, result);
546 break;
547 default:
548 // Should never happen
549 break;
550 }
551
552 return status;
553 }
554
555 static bool process_breathing(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result)
556 {
557 acc_algorithm_mean_sweep(frame, handle->num_points, handle->sweeps_per_frame, handle->start_point, handle->end_point, handle->mean_sweep);
558
559 acc_algorithm_roll_and_push_matrix_f32_complex(handle->sparse_iq_buffer,
560 B_STATIC_LENGTH,
561 handle->num_points_to_analyze,
562 handle->mean_sweep,
563 true);
564
565 acc_algorithm_apply_filter_f32_complex(handle->a_static,
566 handle->filt_sparse_iq_buffer,
567 A_STATIC_LENGTH,
568 handle->num_points_to_analyze,
569 handle->b_static,
570 handle->sparse_iq_buffer,
571 B_STATIC_LENGTH,
572 handle->num_points_to_analyze,
573 handle->filt_sparse_iq,
574 handle->num_points_to_analyze);
575
576 acc_algorithm_roll_and_push_matrix_f32_complex(handle->filt_sparse_iq_buffer,
577 A_STATIC_LENGTH,
578 handle->num_points_to_analyze,
579 handle->filt_sparse_iq,
580 true);
581
582 for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
583 {
584 handle->mean_sweep[i] = handle->mean_sweep[i] - handle->filt_sparse_iq[i];
585 handle->angle[i] = cargf(handle->mean_sweep[i]);
586 }
587
588 if (handle->first)
589 {
590 for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
591 {
592 handle->prev_angle[i] = handle->angle[i];
593 handle->lp_filt_ampl[i] = cabsf(handle->mean_sweep[i]);
594 }
595
596 handle->first = false;
597 }
598
599 for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
600 {
601 handle->lp_filt_ampl[i] = handle->breathing_sf * handle->lp_filt_ampl[i] + (1.0f - handle->breathing_sf) * cabsf(handle->mean_sweep[i]);
602 }
603
604 for (uint16_t i = 0U; i < handle->num_points_to_analyze; i++)
605 {
606 float angle_diff = handle->angle[i] - handle->prev_angle[i];
607 handle->prev_angle[i] = handle->angle[i];
608
609 if ((float)M_PI < angle_diff)
610 {
611 angle_diff -= 2.0f * (float)M_PI;
612 }
613 else if (angle_diff < -(float)M_PI)
614 {
615 angle_diff += 2.0f * (float)M_PI;
616 }
617
618 handle->unwrapped_angle[i] += angle_diff;
619 }
620
621 acc_algorithm_roll_and_push_matrix_f32(handle->angle_buffer, B_ANGLE_LENGTH, handle->num_points_to_analyze, handle->unwrapped_angle, true);
622
623 acc_algorithm_apply_filter_f32(handle->a_angle,
624 handle->filt_angle_buffer,
625 A_ANGLE_LENGTH,
626 handle->num_points_to_analyze,
627 handle->b_angle,
628 handle->angle_buffer,
629 B_ANGLE_LENGTH,
630 handle->num_points_to_analyze,
631 handle->angle,
632 handle->num_points_to_analyze);
633
634 acc_algorithm_roll_and_push_matrix_f32(handle->filt_angle_buffer, A_ANGLE_LENGTH, handle->num_points_to_analyze, handle->angle, true);
635
636 acc_algorithm_roll_and_push_matrix_f32(handle->breathing_motion_buffer,
637 handle->time_series_length,
638 handle->num_points_to_analyze,
639 handle->angle,
640 false);
641
642 if (handle->init_count > handle->time_series_length)
643 {
644 handle->initialized = true;
645 }
646 else
647 {
648 handle->init_count++;
649 }
650
651 if (handle->time_series_length - handle->count_limit <= handle->count)
652 {
653 handle->count = 0;
654
655 if (handle->initialized)
656 {
657 float lp_filt_ampl_sum = 0U;
658
659 for (uint16_t r = 0U; r < handle->time_series_length; r++)
660 {
661 for (uint16_t c = 0U; c < handle->num_points_to_analyze; c++)
662 {
663 handle->windowed_breathing_motion_buffer[r * handle->num_points_to_analyze + c] =
664 handle->breathing_motion_buffer[r * handle->num_points_to_analyze + c] * handle->hamming_window[r];
665 lp_filt_ampl_sum += handle->lp_filt_ampl[c];
666 }
667 }
668
669 acc_algorithm_rfft_matrix(handle->windowed_breathing_motion_buffer,
670 handle->time_series_length,
671 handle->num_points_to_analyze,
672 handle->padded_time_series_length_shift,
673 handle->rfft_output,
674 0U);
675
676 for (uint16_t r = 0U; r < handle->rfft_output_length; r++)
677 {
678 float sum_psd = 0U;
679
680 for (uint16_t c = 0U; c < handle->num_points_to_analyze; c++)
681 {
682 sum_psd += cabsf(handle->rfft_output[r * handle->num_points_to_analyze + c]) * handle->lp_filt_ampl[c];
683 }
684
685 handle->weighted_psd[r] = sum_psd / lp_filt_ampl_sum;
686 }
687
688 uint16_t peak_loc = acc_algorithm_argmax(handle->weighted_psd, handle->rfft_output_length);
689
690 if (peak_loc > 0U)
691 {
692 float freq = acc_algorithm_interpolate_peaks_equidistant(handle->weighted_psd, 0.0f, handle->freq_delta, peak_loc);
693 result->result_ready = true;
694 result->breathing_rate = freq * 60.0f;
695 }
696 }
697 }
698 else
699 {
700 handle->count++;
701 }
702
703 return true;
704 }
ref_app_breathing_handle::init_count
uint16_t init_count
Definition: ref_app_breathing.c:82
REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE
@ REF_APP_BREATHING_APP_STATE_ESTIMATE_BREATHING_RATE
Definition: ref_app_breathing.h:66
acc_integration_mem_calloc
void * acc_integration_mem_calloc(size_t nmemb, size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:597
acc_algorithm_apply_filter_f32
void acc_algorithm_apply_filter_f32(const float *a, const float *filt_data, uint16_t filt_rows, uint16_t filt_cols, const float *b, const float *data, uint16_t data_rows, uint16_t data_cols, float *output, uint16_t output_length)
Apply filter coefficients to filtered data matrix and data matrix.
Definition: acc_algorithm.c:464
acc_detector_presence_config_sweeps_per_frame_set
void acc_detector_presence_config_sweeps_per_frame_set(acc_detector_presence_config_t *presence_config, uint16_t sweeps_per_frame)
Set the number of sweeps per frame.
acc_algorithm_exp_smoothing_coefficient
float acc_algorithm_exp_smoothing_coefficient(float fs, float tc)
Calculate exponential smoothing coefficient.
Definition: acc_algorithm.c:694
ref_app_breathing_handle::breathing_sf
float breathing_sf
Definition: ref_app_breathing.c:50
cargo_result_t::calibration_needed
bool calibration_needed
Definition: example_cargo.h:112
process_breathing
static bool process_breathing(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result)
Definition: ref_app_breathing.c:555
ref_app_breathing_handle::step_length_m
float step_length_m
Definition: ref_app_breathing.c:28
REF_APP_BREATHING_APP_STATE_INIT
@ REF_APP_BREATHING_APP_STATE_INIT
Definition: ref_app_breathing.h:62
acc_detector_presence_destroy
void acc_detector_presence_destroy(acc_detector_presence_handle_t *presence_handle)
Destroy a presence detector identified with the provided handle.
ref_app_breathing_handle::presence_distance
float presence_distance
Definition: ref_app_breathing.c:77
acc_detector_presence_config_hwaas_set
void acc_detector_presence_config_hwaas_set(acc_detector_presence_config_t *presence_config, uint16_t hwaas)
Set the hardware accelerated average samples (HWAAS)
reinit_breathing
static bool reinit_breathing(ref_app_breathing_handle_t *handle, uint16_t start_point, uint16_t end_point)
Definition: ref_app_breathing.c:467
ref_app_breathing_handle::angle
float * angle
Definition: ref_app_breathing.c:61
ref_app_breathing_handle::count
uint16_t count
Definition: ref_app_breathing.c:83
ref_app_breathing_handle::angle_buffer
float * angle_buffer
Definition: ref_app_breathing.c:65
buffer
void * buffer
Definition: i2c_example_cargo.c:40
acc_detector_presence_metadata_t::step_length_m
float step_length_m
Definition: acc_detector_presence.h:108
sensor_cal_result
acc_cal_result_t sensor_cal_result
Definition: i2c_example_cargo.c:36
ref_app_breathing_handle::filt_sparse_iq_buffer
float complex * filt_sparse_iq_buffer
Definition: ref_app_breathing.c:59
ref_app_breathing_handle::app_state
ref_app_breathing_app_state_t app_state
Definition: ref_app_breathing.c:46
ref_app_breathing_config_create
ref_app_breathing_config_t * ref_app_breathing_config_create(void)
Create a configuration for the ref app breathing.
Definition: ref_app_breathing.c:100
acc_detector_presence_config_auto_profile_set
void acc_detector_presence_config_auto_profile_set(acc_detector_presence_config_t *presence_config, bool enable)
Enable automatic selection of profile based on start point of measurement.
presence_distance
static float presence_distance
Definition: i2c_presence_detector.c:49
acc_alg_basic_utils.h
acc_int16_complex_t
Data type for interger-based representation of complex numbers.
Definition: acc_definitions_common.h:40
ref_app_breathing_handle::padded_time_series_length
uint16_t padded_time_series_length
Definition: ref_app_breathing.c:41
acc_algorithm_interpolate_peaks_equidistant
float acc_algorithm_interpolate_peaks_equidistant(const float *y, float x_start, float x_delta, uint16_t peak_idx)
Interpolate equidistant peaks.
Definition: acc_algorithm.c:330
acc_algorithm_roll_and_push_matrix_f32
void acc_algorithm_roll_and_push_matrix_f32(float *data, uint16_t rows, uint16_t cols, const float *column, bool pos_shift)
Roll row elements and push a new column.
Definition: acc_algorithm.c:169
acc_cal_result_t
The result from a completed calibration.
Definition: acc_definitions_a121.h:30
acc_detector_presence_config_frame_rate_set
void acc_detector_presence_config_frame_rate_set(acc_detector_presence_config_t *presence_config, float frame_rate)
Set the frame rate.
acc_detector_presence_metadata_t::start_m
float start_m
Definition: acc_detector_presence.h:95
ref_app_breathing.h
update_presence_distance
static void update_presence_distance(ref_app_breathing_handle_t *handle, float presence_distance)
Definition: ref_app_breathing.c:450
ref_app_breathing_result_t
Breathing application results container.
Definition: ref_app_breathing.h:72
ref_app_breathing_handle::windowed_breathing_motion_buffer
float * windowed_breathing_motion_buffer
Definition: ref_app_breathing.c:69
ref_app_breathing_handle::sparse_iq_buffer
float complex * sparse_iq_buffer
Definition: ref_app_breathing.c:58
ref_app_breathing_handle::presence_handle
acc_detector_presence_handle_t * presence_handle
Definition: ref_app_breathing.c:25
ref_app_breathing_prepare
bool ref_app_breathing_prepare(ref_app_breathing_handle_t *handle, ref_app_breathing_config_t *config, acc_sensor_t *sensor, const acc_cal_result_t *sensor_cal_result, void *buffer, uint32_t buffer_size)
Prepare the application to do a measurement.
Definition: ref_app_breathing.c:358
ref_app_breathing_handle::distance_determination_count
uint16_t distance_determination_count
Definition: ref_app_breathing.c:37
acc_integration.h
acc_detector_presence_get_buffer_size
bool acc_detector_presence_get_buffer_size(const acc_detector_presence_handle_t *presence_handle, uint32_t *buffer_size)
Get the buffer size needed for the provided presence detector handle.
ref_app_breathing_handle::end_point
uint16_t end_point
Definition: ref_app_breathing.c:32
ref_app_breathing_handle::rfft_output_length
uint16_t rfft_output_length
Definition: ref_app_breathing.c:71
ref_app_breathing_handle::intra_detection_threshold
float intra_detection_threshold
Definition: ref_app_breathing.c:44
config
cargo_config_t config
Definition: i2c_example_cargo.c:34
acc_detector_presence_result_t::presence_detected
bool presence_detected
Definition: acc_detector_presence.h:51
ref_app_breathing_handle::frame_rate
float frame_rate
Definition: ref_app_breathing.c:33
ref_app_breathing_handle::presence_distance_threshold
float presence_distance_threshold
Definition: ref_app_breathing.c:80
REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE
@ REF_APP_BREATHING_APP_STATE_INTRA_PRESENCE
Definition: ref_app_breathing.h:64
ref_app_breathing_handle::distance_determination_counter
uint16_t distance_determination_counter
Definition: ref_app_breathing.c:75
acc_detector_presence_config_intra_detection_threshold_set
void acc_detector_presence_config_intra_detection_threshold_set(acc_detector_presence_config_t *presence_config, float intra_detection_threshold)
Set the detection threshold for the intra-frame presence detection.
determine_state
static void determine_state(ref_app_breathing_handle_t *handle, acc_detector_presence_result_t *presence_result)
Definition: ref_app_breathing.c:426
acc_integration_mem_alloc
void * acc_integration_mem_alloc(size_t size)
Allocate dynamic memory.
Definition: acc_integration_stm32.c:592
ref_app_breathing_handle::time_series_length
uint16_t time_series_length
Definition: ref_app_breathing.c:39
ref_app_breathing_handle::sweeps_per_frame
uint16_t sweeps_per_frame
Definition: ref_app_breathing.c:43
ref_app_breathing_handle::lp_filt_ampl
float * lp_filt_ampl
Definition: ref_app_breathing.c:63
ref_app_breathing_handle::prev_angle
float * prev_angle
Definition: ref_app_breathing.c:62
ref_app_breathing_handle::hamming_window
float * hamming_window
Definition: ref_app_breathing.c:68
ref_app_breathing_handle::a_angle
float a_angle[(4U)]
Definition: ref_app_breathing.c:55
acc_detector_presence_result_t
Presence detector results container.
Definition: acc_detector_presence.h:46
buffer_size
uint32_t buffer_size
Definition: i2c_example_cargo.c:41
ref_app_breathing_handle::start_point
int32_t start_point
Definition: ref_app_breathing.c:29
acc_detector_presence_config_inter_frame_presence_timeout_set
void acc_detector_presence_config_inter_frame_presence_timeout_set(acc_detector_presence_config_t *presence_config, uint16_t inter_frame_presence_timeout)
Set the inter-frame presence timeout in seconds.
acc_algorithm_butter_lowpass
void acc_algorithm_butter_lowpass(float freq, float fs, float *b, float *a)
Design a 2nd order digital Butterworth lowpass filter.
Definition: acc_algorithm.c:337
ref_app_breathing_handle::breathing_motion_buffer
float * breathing_motion_buffer
Definition: ref_app_breathing.c:67
sensor
acc_sensor_t * sensor
Definition: i2c_example_cargo.c:33
acc_detector_presence_metadata_t::num_points
uint16_t num_points
Definition: acc_detector_presence.h:115
acc_algorithm_argmax
uint16_t acc_algorithm_argmax(const float *data, uint16_t data_length)
Find index of largest element in the array.
Definition: acc_algorithm.c:305
ref_app_breathing_handle::filt_angle_buffer
float * filt_angle_buffer
Definition: ref_app_breathing.c:66
ref_app_breathing_handle::start_m
float start_m
Definition: ref_app_breathing.c:27
ref_app_breathing_handle::time_series_length_s
uint16_t time_series_length_s
Definition: ref_app_breathing.c:38
ref_app_breathing_handle::highest_freq
float highest_freq
Definition: ref_app_breathing.c:35
acc_detector_presence_config_destroy
void acc_detector_presence_config_destroy(acc_detector_presence_config_t *presence_config)
Destroy a presence detector configuration.
acc_detector_presence_metadata_t
Definition: acc_detector_presence.h:88
ref_app_breathing_handle::rfft_output
float complex * rfft_output
Definition: ref_app_breathing.c:70
ref_app_breathing_handle::a_static
float a_static[(2U)]
Definition: ref_app_breathing.c:53
acc_algorithm_rfft_matrix
void acc_algorithm_rfft_matrix(const float *data, uint16_t rows, uint16_t cols, uint16_t length_shift, float complex *output, uint16_t axis)
1D Fast Fourier Transform for real input matrix
Definition: acc_algorithm.c:597
acc_detector_presence_config_end_set
void acc_detector_presence_config_end_set(acc_detector_presence_config_t *presence_config, float end)
Set the end point of measurement interval in meters.
acc_detector_presence_config_intra_output_time_const_set
void acc_detector_presence_config_intra_output_time_const_set(acc_detector_presence_config_t *presence_config, float intra_output_time_const)
Set the time constant for the output in the intra-frame part.
handle
cargo_handle_t * handle
Definition: i2c_example_cargo.c:35
ref_app_breathing_handle::base_presence_distance
float base_presence_distance
Definition: ref_app_breathing.c:79
result
cargo_result_t result
Definition: i2c_example_cargo.c:43
A_ANGLE_LENGTH
#define A_ANGLE_LENGTH
Definition: ref_app_breathing.c:21
printf
#define printf
Definition: printf.h:60
ref_app_breathing_handle::base_presence_dist
bool base_presence_dist
Definition: ref_app_breathing.c:78
ref_app_breathing_handle::initialized
bool initialized
Definition: ref_app_breathing.c:84
acc_detector_presence_result_t::intra_presence_score
float intra_presence_score
Definition: acc_detector_presence.h:55
validate_config
static bool validate_config(ref_app_breathing_config_t *config)
Definition: ref_app_breathing.c:399
REF_APP_BREATHING_APP_STATE_NO_PRESENCE
@ REF_APP_BREATHING_APP_STATE_NO_PRESENCE
Definition: ref_app_breathing.h:63
M_PI
#define M_PI
Definition: acc_alg_basic_utils.h:14
ref_app_breathing_handle::presence_sf
float presence_sf
Definition: ref_app_breathing.c:49
acc_detector_presence_process
bool acc_detector_presence_process(acc_detector_presence_handle_t *presence_handle, void *buffer, acc_detector_presence_result_t *result)
Process the data according to the configuration used in acc_detector_presence_config_create.
acc_detector_presence_config_inter_output_time_const_set
void acc_detector_presence_config_inter_output_time_const_set(acc_detector_presence_config_t *presence_config, float inter_output_time_const)
Set the time constant for the output in the inter-frame part.
ref_app_breathing_get_buffer_size
bool ref_app_breathing_get_buffer_size(ref_app_breathing_handle_t *handle, uint32_t *buffer_size)
Get the buffer size needed for the provided ref app breathing handle.
Definition: ref_app_breathing.c:353
cargo_handle::presence_handle
acc_detector_presence_handle_t * presence_handle
Definition: example_cargo.c:33
B_ANGLE_LENGTH
#define B_ANGLE_LENGTH
Definition: ref_app_breathing.c:20
ref_app_breathing_handle::weighted_psd
float * weighted_psd
Definition: ref_app_breathing.c:72
acc_algorithm_mean_sweep
void acc_algorithm_mean_sweep(const acc_int16_complex_t *frame, uint16_t num_points, uint16_t sweeps_per_frame, uint16_t start_point, uint16_t end_point, float complex *sweep)
Calculate mean sweep of a frame from start_point to end_point.
Definition: acc_algorithm.c:523
ref_app_breathing_handle::num_points
uint16_t num_points
Definition: ref_app_breathing.c:42
ref_app_breathing_handle::unwrapped_angle
float * unwrapped_angle
Definition: ref_app_breathing.c:64
ref_app_breathing_handle::lowest_freq
float lowest_freq
Definition: ref_app_breathing.c:34
acc_detector_presence_prepare
bool acc_detector_presence_prepare(const acc_detector_presence_handle_t *presence_handle, acc_detector_presence_config_t *presence_config, acc_sensor_t *sensor, const acc_cal_result_t *cal_result, void *buffer, uint32_t buffer_size)
Prepare the detector to do a measurement.
ref_app_breathing_handle::mean_sweep
float complex * mean_sweep
Definition: ref_app_breathing.c:57
acc_algorithm_fftfreq_delta
float acc_algorithm_fftfreq_delta(uint16_t n, float d)
Calculate delta between frequency bins in rfft.
Definition: acc_algorithm.c:652
ref_app_breathing_destroy
void ref_app_breathing_destroy(ref_app_breathing_handle_t *handle)
Destroy a handle for the ref app breathing.
Definition: ref_app_breathing.c:265
B_STATIC_LENGTH
#define B_STATIC_LENGTH
Definition: ref_app_breathing.c:18
perform_action_based_on_state
static bool perform_action_based_on_state(ref_app_breathing_handle_t *handle, acc_int16_complex_t *frame, ref_app_breathing_result_t *result)
Definition: ref_app_breathing.c:490
acc_detector_presence_config_t
struct acc_detector_presence_config acc_detector_presence_config_t
Definition: acc_detector_presence.h:41
acc_detector_presence_config_sweeps_per_frame_get
uint16_t acc_detector_presence_config_sweeps_per_frame_get(const acc_detector_presence_config_t *presence_config)
Get the number of sweeps per frame.
REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE
@ REF_APP_BREATHING_APP_STATE_DETERMINE_DISTANCE
Definition: ref_app_breathing.h:65
ref_app_breathing_handle::num_points_to_analyze_half_width
uint16_t num_points_to_analyze_half_width
Definition: ref_app_breathing.c:30
ref_app_breathing_handle::prev_app_state
ref_app_breathing_app_state_t prev_app_state
Definition: ref_app_breathing.c:47
acc_algorithm.h
acc_detector_presence_config_frame_rate_get
float acc_detector_presence_config_frame_rate_get(const acc_detector_presence_config_t *presence_config)
Get the frame rate.
acc_detector_presence_config_profile_set
void acc_detector_presence_config_profile_set(acc_detector_presence_config_t *presence_config, acc_config_profile_t profile)
Set a profile.
acc_algorithm_roll_and_push_matrix_f32_complex
void acc_algorithm_roll_and_push_matrix_f32_complex(float complex *data, uint16_t rows, uint16_t cols, const float complex *column, bool pos_shift)
Roll row elements and push a new column.
Definition: acc_algorithm.c:203
acc_algorithm_get_fwhm
float acc_algorithm_get_fwhm(acc_config_profile_t profile)
Get the envelope Full Width Half Maximum in meters given a profile.
Definition: acc_algorithm.c:745
acc_integration_mem_free
void acc_integration_mem_free(void *ptr)
Free dynamic memory.
Definition: acc_integration_stm32.c:602
ref_app_breathing_config_destroy
void ref_app_breathing_config_destroy(ref_app_breathing_config_t *config)
Destory a configuration for the ref app breathing.
Definition: ref_app_breathing.c:143
ref_app_breathing_create
ref_app_breathing_handle_t * ref_app_breathing_create(ref_app_breathing_config_t *config)
Create a handle for the ref app breathing.
Definition: ref_app_breathing.c:156
ref_app_breathing_handle::num_points_to_analyze
uint16_t num_points_to_analyze
Definition: ref_app_breathing.c:31
acc_detector_presence_create
acc_detector_presence_handle_t * acc_detector_presence_create(acc_detector_presence_config_t *presence_config, acc_detector_presence_metadata_t *metadata)
Create a presence detector with the provided configuration.
ref_app_breathing_handle
Definition: ref_app_breathing.c:23
acc_detector_presence_config_intra_detection_threshold_get
float acc_detector_presence_config_intra_detection_threshold_get(const acc_detector_presence_config_t *presence_config)
Get the detection threshold for the intra-frame presence detection.
acc_detector_presence_config_profile_get
acc_config_profile_t acc_detector_presence_config_profile_get(const acc_detector_presence_config_t *presence_config)
Get the currently set profile.
acc_algorithm_butter_bandpass
void acc_algorithm_butter_bandpass(float min_freq, float max_freq, float fs, float *b, float *a)
Design a 2nd order digital Butterworth bandpass filter.
Definition: acc_algorithm.c:379
acc_detector_presence_handle_t
struct acc_detector_presence_handle acc_detector_presence_handle_t
Definition: acc_detector_presence.h:34
acc_detector_presence_config_create
acc_detector_presence_config_t * acc_detector_presence_config_create(void)
Create a configuration for a presence detector.
ref_app_breathing_config_t
Breathing application config container.
Definition: ref_app_breathing.h:25
ref_app_breathing_handle::use_presence_processor
uint16_t use_presence_processor
Definition: ref_app_breathing.c:36
ref_app_breathing_handle::b_static
float b_static[(3U)]
Definition: ref_app_breathing.c:52
ref_app_breathing_handle::count_limit
uint16_t count_limit
Definition: ref_app_breathing.c:85
ref_app_breathing_process
bool ref_app_breathing_process(ref_app_breathing_handle_t *handle, void *buffer, ref_app_breathing_result_t *result)
Process the data.
Definition: ref_app_breathing.c:368
ref_app_breathing_handle::first
bool first
Definition: ref_app_breathing.c:81
acc_detector_presence_config_start_set
void acc_detector_presence_config_start_set(acc_detector_presence_config_t *presence_config, float start)
Set the start point of measurement interval in meters.
ref_app_breathing_handle::padded_time_series_length_shift
uint16_t padded_time_series_length_shift
Definition: ref_app_breathing.c:40
ref_app_breathing_handle::filt_sparse_iq
float complex * filt_sparse_iq
Definition: ref_app_breathing.c:60
acc_detector_presence.h
acc_algorithm_apply_filter_f32_complex
void acc_algorithm_apply_filter_f32_complex(const float *a, const float complex *filt_data, uint16_t filt_rows, uint16_t filt_cols, const float *b, const float complex *data, uint16_t data_rows, uint16_t data_cols, float complex *output, uint16_t output_length)
Apply filter coefficients to filtered data matrix and data matrix.
Definition: acc_algorithm.c:491
acc_detector_presence_config_auto_step_length_set
void acc_detector_presence_config_auto_step_length_set(acc_detector_presence_config_t *presence_config, bool enable)
Enable automatic selection of step length based on the profile.
ref_app_breathing_handle::presence_init
bool presence_init
Definition: ref_app_breathing.c:76
acc_algorithm_hamming
void acc_algorithm_hamming(uint16_t n, float *window)
Calculate hamming window for a specified number of points.
Definition: acc_algorithm.c:721
acc_sensor_t
struct acc_sensor acc_sensor_t
Definition: acc_sensor.h:31
ref_app_breathing_handle::b_angle
float b_angle[(5U)]
Definition: ref_app_breathing.c:54
acc_detector_presence_config_step_length_set
void acc_detector_presence_config_step_length_set(acc_detector_presence_config_t *presence_config, uint16_t step_length)
Set the step length in points.
ACC_CONFIG_PROFILE_3
@ ACC_CONFIG_PROFILE_3
Definition: acc_definitions_a121.h:54
acc_detector_presence_config_automatic_subsweeps_set
void acc_detector_presence_config_automatic_subsweeps_set(acc_detector_presence_config_t *presence_config, bool automatic_subsweeps)
Set if automatic subsweeps should be used.
ref_app_breathing_app_state_t
ref_app_breathing_app_state_t
State of the application.
Definition: ref_app_breathing.h:60
ref_app_breathing_handle::freq_delta
float freq_delta
Definition: ref_app_breathing.c:73
A_STATIC_LENGTH
#define A_STATIC_LENGTH
Definition: ref_app_breathing.c:19
acc_detector_presence_config_inter_frame_fast_cutoff_set
void acc_detector_presence_config_inter_frame_fast_cutoff_set(acc_detector_presence_config_t *presence_config, float inter_frame_fast_cutoff)
Set the cutoff frequency of the low pass filter for the fast filtered absolute sweep mean.