@@ -78,9 +78,24 @@ MldpReturn_t filterStdDev(const float *data_in, const int in_size, float *data_o
7878 return MLDP_SUCCESS ;
7979}
8080
81+ // This combined function is more efficient than calling filterMean and filterStdDev separately
82+ static inline void calcMeanAndStdDev (const float * data_in , const int in_size , float * mean , float * std_dev ) {
83+ float sum = 0 ;
84+ for (int i = 0 ; i < in_size ; i ++ ) {
85+ sum += data_in [i ];
86+ }
87+ const float _mean = sum / (float )in_size ;
88+
89+ float sum_of_squares = 0 ;
90+ for (int i = 0 ; i < in_size ; i ++ ) {
91+ float f = data_in [i ] - _mean ;
92+ sum_of_squares += f * f ;
93+ }
94+ * std_dev = sqrtf (sum_of_squares / (float )in_size );
95+ * mean = _mean ;
96+ }
97+
8198// Count the number of peaks
82- // Warning! This can allocate 5x the in_size of the data in the stack
83- // so ensure DEVICE_STACK_SIZE is appropriately set
8499MldpReturn_t filterPeaks (const float * data_in , const int in_size , float * data_out , const int out_size ) {
85100 const int lag = 5 ;
86101 const float threshold = 3.5 ;
@@ -90,71 +105,50 @@ MldpReturn_t filterPeaks(const float *data_in, const int in_size, float *data_ou
90105 return MLDP_ERROR_CONFIG ;
91106 }
92107
93- static float * signals = NULL ;
94- static float * filtered_y = NULL ;
95- static float * avg_filter = NULL ;
96- static float * std_filter = NULL ;
97- static int arrays_alloc_size = 0 ;
98- float lead_in [lag ];
99-
100108 // Keep memory allocated between calls to avoid malloc/free overhead
101- if (arrays_alloc_size < in_size ) {
102- free (signals ); free (filtered_y ); free (avg_filter ); free (std_filter );
103- signals = (float * )malloc (in_size * sizeof (float ));
109+ static float * filtered_y = NULL ;
110+ static int alloc_size = 0 ;
111+ if (alloc_size < in_size ) {
112+ free (filtered_y );
104113 filtered_y = (float * )malloc (in_size * sizeof (float ));
105- avg_filter = (float * )malloc (in_size * sizeof (float ));
106- std_filter = (float * )malloc (in_size * sizeof (float ));
107- if (signals == NULL || filtered_y == NULL || avg_filter == NULL || std_filter == NULL ) {
108- free (signals ); free (filtered_y ); free (avg_filter ); free (std_filter );
109- signals = NULL ; filtered_y = NULL ; avg_filter = NULL ; std_filter = NULL ;
110- arrays_alloc_size = 0 ;
114+ if (filtered_y == NULL ) {
115+ alloc_size = 0 ;
111116 return MLDP_ERROR_ALLOC ;
112117 }
113- arrays_alloc_size = in_size ;
118+ alloc_size = in_size ;
114119 }
115- memset (signals , 0 , in_size * sizeof (float ));
116120 memcpy (filtered_y , data_in , lag * sizeof (float ));
117- memcpy (lead_in , data_in , lag * sizeof (float ));
118121
119122 float mean_lag , std_dev_lag ;
120- MldpReturn_t mean_result = filterMean (lead_in , lag , & mean_lag , 1 );
121- MldpReturn_t std_dev_result = filterStdDev (lead_in , lag , & std_dev_lag , 1 );
122- if (std_dev_result != MLDP_SUCCESS || mean_result != MLDP_SUCCESS ) {
123- return MLDP_ERROR_CONFIG ;
124- }
125-
126- avg_filter [lag - 1 ] = mean_lag ;
127- std_filter [lag - 1 ] = std_dev_lag ;
123+ calcMeanAndStdDev (filtered_y , lag , & mean_lag , & std_dev_lag );
128124
125+ int previous_signal = 0 ;
129126 int peaksCounter = 0 ;
130127 for (int i = lag ; i < in_size ; i ++ ) {
131- const float diff = fabsf (data_in [i ] - avg_filter [i - 1 ]);
128+ int current_signal ;
129+ const float diff = fabsf (data_in [i ] - mean_lag );
132130 if (
133131 diff > 0.1f &&
134- diff > threshold * std_filter [ i - 1 ]
132+ diff > threshold * std_dev_lag
135133 ) {
136- if (data_in [i ] > avg_filter [ i - 1 ] ) {
137- signals [ i ] = +1 ; // positive signal
138- if (i - 1 > 0 && signals [ i - 1 ] == 0 ) {
134+ if (data_in [i ] > mean_lag ) {
135+ current_signal = +1 ; // positive signal
136+ if (previous_signal == 0 ) {
139137 peaksCounter ++ ;
140138 }
141139 } else {
142- signals [ i ] = -1 ; // negative signal
140+ current_signal = -1 ; // negative signal
143141 }
144142 // make influence lower
145143 filtered_y [i ] = influence * data_in [i ] + (1.0f - influence ) * filtered_y [i - 1 ];
146144 } else {
147- signals [ i ] = 0 ; // no signal
145+ current_signal = 0 ; // no signal
148146 filtered_y [i ] = data_in [i ];
149147 }
148+ previous_signal = current_signal ;
150149
151150 // adjust the filters
152- float y_lag [lag ];
153- memcpy (y_lag , & filtered_y [i - lag ], lag * sizeof (float ));
154- filterMean (y_lag , lag , & mean_lag , 1 );
155- filterStdDev (y_lag , lag , & std_dev_lag , 1 );
156- avg_filter [i ] = mean_lag ;
157- std_filter [i ] = std_dev_lag ;
151+ calcMeanAndStdDev (& filtered_y [i - lag ], lag , & mean_lag , & std_dev_lag );
158152 }
159153 * data_out = peaksCounter ;
160154
0 commit comments