soundstream: simplify profile collection

- do one trip only to bound runtime
- add stats_enable/stats_disable noop functions that can be hooked
  in the simulator or renode to control profiling
- poke tohost on exit to signal simulator the app is done
- (while here) lint

Bypass-Presubmit-Reason: no sencha CI tests

Change-Id: Ie683d743391588089df759e0be4474b10ae9ae09
diff --git a/sw/device/cheriot/soundstream/soundstream.cc b/sw/device/cheriot/soundstream/soundstream.cc
index 6d6c06f..9e880da 100644
--- a/sw/device/cheriot/soundstream/soundstream.cc
+++ b/sw/device/cheriot/soundstream/soundstream.cc
@@ -28,10 +28,16 @@
 
 #define ABS(x) (x > 0 ? x : -x)
 
-//#define kSamples (5 * 16000)
-#define kSamples (2000) // NB: reduced sample count for slow renode
+// #define kSamples (5 * 16000)
+#define kSamples (2000)  // NB: reduce sample count for slow renode
 #define kFilterSamples (256)
 
+// Marker symbols to hook to enable/disable profiling
+extern "C" {
+void __attribute__((noinline)) stats_enable(void) { asm(""); }
+void __attribute__((noinline)) stats_disable(void) { asm(""); }
+}
+
 void __cheri_compartment("soundstream") entry(void) {
   Debug::log("soundstream (Thread {})", thread_id_get());
 
@@ -56,7 +62,13 @@
 
   Debug::log("Setup complete");
 
+  stats_enable();
+// NB: once around the loop for collecting profile data
+#if 0
   while (true) {
+#else
+  {
+#endif
     // TODO(sleffler): need custom security core code running and
     //   a way to toggle the gpio associated with the button; for now
     //   just force it to appear as though the button has been pressed.
@@ -115,7 +127,7 @@
     int32_t max = INT16_MIN;
     int32_t min = INT16_MAX;
     for (int i = 1; i < (samples_captured * 2); i += 2) {
-      int16_t* samples_s16 = (int16_t*)samples;
+      int16_t* samples_s16 = reinterpret_cast<int16_t*>(samples);
       int32_t sample = samples_s16[i];
       if (sample < min) {
         min = sample;
@@ -131,7 +143,7 @@
     int32_t scale_min = ABS(((int32_t)min * 100) / ((int32_t)INT16_MIN));
     int32_t scale = scale_max > scale_min ? scale_max : scale_min;
     for (int i = 1; i < (samples_captured * 2); i += 2) {
-      int16_t* samples_s16 = (int16_t*)samples;
+      int16_t* samples_s16 = reinterpret_cast<int16_t*>(samples);
       int16_t sample = samples_s16[i];
       int16_t scaled_sample = (int16_t)(((int32_t)sample * 100) / scale);
       scaled_sample = (((int32_t)scaled_sample * 75) / 100);
@@ -151,7 +163,7 @@
 
     for (int i = 0; i < iterations_to_process; ++i) {
       Debug::log("Iteration {}", i);
-      int16_t* samples_s16 = (int16_t*)samples;
+      int16_t* samples_s16 = reinterpret_cast<int16_t*>(samples);
       // Extract left channel audio
       for (int j = 0; j < 320; ++j) {
         process_buffer[j] = samples_s16[(i * 320 * 2) + (j * 2) + 1];
@@ -165,7 +177,8 @@
       ml_top_wait_for_finish();
 
       ml_top_get_output_header(&header);
-      Debug::Assert(header.length == sizeof(result_buffer), "Unexpected ML result size");
+      Debug::Assert(header.length == sizeof(result_buffer),
+                    "Unexpected ML result size");
       ml_top_get_output_data(&header, result_buffer);
 
       encode((const unsigned char*)result_buffer, sizeof(result_buffer),
@@ -177,5 +190,6 @@
     Debug::log("[sound]::ENCODER: done");
     Debug::log("Done with processing.");
   }
-  panic();
+  stats_disable();
+  simulation_exit(0);
 }