@@ -145,33 +145,36 @@ class SensorI2SMic final: public Sensor
145145 _frame_index = 0 ;
146146 _data_bytes_available = 0 ;
147147
148- if (_data_buffer)
148+ if (_data_buffer) [[likely]]
149149 {
150- if (_data_buffer.use_count () > 1 )
150+ if (_data_buffer.use_count () > 1 ) [[unlikely]]
151151 {
152152 LOG (ERROR, " Data buffer is already in use by another process" );
153153 return STATUS (EBUSY, " Data buffer is already in use" );
154154 }
155+
155156 _data_buffer.reset ();
156157 }
157158
158- if (_rx_chan)
159+ if (_rx_chan) [[likely]]
159160 {
160161 auto ret = i2s_channel_disable (_rx_chan);
161- if (ret != ESP_OK)
162+ if (ret != ESP_OK) [[unlikely]]
162163 {
163164 LOG (ERROR, " Failed to disable I2S channel: %s" , esp_err_to_name (ret));
164165 return STATUS (EIO, " Failed to disable I2S channel" );
165166 }
166167 ret = i2s_del_channel (_rx_chan);
167- if (ret != ESP_OK)
168+ if (ret != ESP_OK) [[unlikely]]
168169 {
169170 LOG (ERROR, " Failed to delete I2S channel: %s" , esp_err_to_name (ret));
170171 return STATUS (EIO, " Failed to delete I2S channel" );
171172 }
172173 _rx_chan = nullptr ;
173174 }
174175
176+ _info.status = Status::Uninitialized;
177+
175178 return STATUS_OK ();
176179 }
177180
@@ -213,6 +216,12 @@ class SensorI2SMic final: public Sensor
213216 inline core::Status readDataFrame (core::DataFrame<std::unique_ptr<core::Tensor>> &data_frame,
214217 size_t batch_size) noexcept override
215218 {
219+ if (batch_size == 0 ) [[unlikely]]
220+ {
221+ LOG (ERROR, " Batch size cannot be zero" );
222+ return STATUS (EINVAL, " Batch size cannot be zero" );
223+ }
224+
216225 if (!initialized ()) [[unlikely]]
217226 {
218227 LOG (ERROR, " Sensor is not initialized" );
@@ -229,33 +238,21 @@ class SensorI2SMic final: public Sensor
229238 return STATUS (EBUSY, " Data buffer is already in use" );
230239 }
231240
232- if (batch_size == 0 ) [[unlikely]]
241+ if (batch_size > _data_buffer_capacity_frames ) [[unlikely]]
233242 {
234- LOG (ERROR , " Batch size cannot be zero " );
235- return STATUS (EINVAL, " Batch size cannot be zero " ) ;
243+ LOG (WARNING , " Batch size exceeds buffer capacity: %zu > %zu " , batch_size, _data_buffer_capacity_frames );
244+ batch_size = _data_buffer_capacity_frames ;
236245 }
237246
238247 const std::lock_guard<std::mutex> lock (_lock);
239248
240249 _info.status = Status::Locked;
241250
242- const size_t available = internalDataAvailable ();
243- if (available > batch_size) [[unlikely]]
244- {
245- [[maybe_unused]] const auto discarded = internalDataDiscard (available - batch_size);
246- LOG (DEBUG, " Discarded %zu staled frames from data buffer" , discarded);
247- }
248- while (internalDataAvailable () < batch_size)
249- {
250- vTaskDelay (pdMS_TO_TICKS (5 ));
251- }
252-
253251 data_frame.timestamp = std::chrono::steady_clock::now ();
254252
255253 size_t read = 0 ;
256254 {
257- size_t size
258- = std::min (static_cast <size_t >(batch_size * _channels * sizeof (int16_t )), _data_buffer_capacity_bytes);
255+ size_t size = batch_size * _channels * sizeof (int16_t );
259256 auto ret = i2s_channel_read (_rx_chan, _data_buffer.get (), size, &read,
260257 pdMS_TO_TICKS ((_buffered_duration + 1 ) * 1000 ));
261258 if (ret != ESP_OK) [[unlikely]]
@@ -264,12 +261,12 @@ class SensorI2SMic final: public Sensor
264261 _info.status = Status::Idle;
265262 return STATUS (EIO, " Failed to read data from I2S channel" );
266263 }
267- internalConsumeData (size );
264+ internalConsumeData (read );
268265
269266 if (read != size) [[unlikely]]
270267 {
271268 LOG (WARNING, " Read %zu bytes, expected %zu bytes" , read, size);
272- if (read == 0 )
269+ if (! read) [[unlikely]]
273270 {
274271 _info.status = Status::Idle;
275272 return STATUS (EIO, " No data read from I2S channel" );
@@ -278,9 +275,9 @@ class SensorI2SMic final: public Sensor
278275 read = batch_size * (_channels * sizeof (int16_t ));
279276 }
280277 }
281-
282278 data_frame.data = core::Tensor::create (core::Tensor::Type::Int16,
283279 core::Tensor::Shape (static_cast <int >(batch_size), static_cast <int >(_channels)), _data_buffer, read);
280+
284281 data_frame.index = _frame_index;
285282 _frame_index += batch_size;
286283
@@ -303,7 +300,7 @@ class SensorI2SMic final: public Sensor
303300 {
304301 const size_t new_data_bytes_available = std::min (data_bytes_available + size, _data_buffer_capacity_bytes);
305302 if (_data_bytes_available.compare_exchange_strong (data_bytes_available, new_data_bytes_available,
306- std::memory_order_release, std::memory_order_relaxed))
303+ std::memory_order_release, std::memory_order_relaxed)) [[likely]]
307304 {
308305 return false ;
309306 }
@@ -339,13 +336,17 @@ class SensorI2SMic final: public Sensor
339336
340337 inline void internalConsumeData (size_t size) noexcept
341338 {
339+ if (!size) [[unlikely]]
340+ {
341+ return ;
342+ }
342343 size_t data_bytes_available = _data_bytes_available.load (std::memory_order_acquire);
343344 while (1 )
344345 {
345346 size = std::min (size, data_bytes_available);
346347 const size_t new_data_bytes_available = data_bytes_available - size;
347348 if (_data_bytes_available.compare_exchange_strong (data_bytes_available, new_data_bytes_available,
348- std::memory_order_release, std::memory_order_relaxed))
349+ std::memory_order_release, std::memory_order_relaxed)) [[likely]]
349350 {
350351 return ;
351352 }
0 commit comments