/*
 * Copyright 2023 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "soundstream.h"

#include <fail-simulator-on-error.h>
#include <thread.h>

#include <debug.hh>

#include "hw/top_matcha/sw/autogen/top_matcha.h"

/// Expose debugging features unconditionally for this compartment.
using Debug = ConditionalDebug<true, "SOUNDSTREAM">;

#define ABS(x) (x > 0 ? x : -x)

// #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());

  i2s_init();
  ml_top_init();
#if DEVICE_EXISTS_mailbox
  mailbox_init();
#endif

  i2s_rxfifo_clear();
  i2s_irq_acknowledge_all();
  i2s_irq_set_enabled(kI2sIrqRxWatermark, /*enabled=*/true);

  Debug::log("Loading Kelvin binary from SPI");
  ml_top_load_file_from_tar("kelvin.bin");

  // NB: the stack is 4KiB so this uses 1/4 of it
  int16_t samples_left[kFilterSamples] = {0};
  int16_t samples_right[kFilterSamples] = {0};
  size_t index_left = 0;
  size_t index_right = 0;
  int32_t total_left = 0;
  int32_t total_right = 0;

  static int32_t samples[kSamples];
  memset(samples, 0xa5, sizeof(int32_t) * kSamples);

  Debug::log("Setup complete");

  stats_enable();
// NB: once around the loop for collecting profile data
#if 0
  while (true) {
#else
  {
#endif
#if DEVICE_EXISTS_mailbox
    // 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.
    mailbox_set_button_pressed(true);

    // Wait until the record switch is pushed
    Debug::log("Wait for button press...");
    mailbox_wait_for_button_pressed();

    mailbox_set_led(/*enabled=*/true);
#else
#endif
    Debug::log("Start recording (max {} samples)...", kSamples);
    i2s_record_begin();

    // Record until our buffer is full or the switch is released.
    int sample = 0;
    while (sample < kSamples
#if DEVICE_EXISTS_mailbox
           && mailbox_button_pressed()
#else
#endif
    ) {
      i2s_irq_set_enabled(kI2sIrqRxWatermark, /*enabled=*/true);

      i2s_wait_for_rx_watermark();

      while (!i2s_rxfifo_is_empty()) {
        uint32_t reg_val = i2s_get_rdata();
        // For each sample, split into left and right channel values,
        // and update the moving average.
        int16_t left = reg_val >> 16;
        int16_t right = reg_val & 0xFFFF;
        total_left -= samples_left[index_left];
        total_right -= samples_right[index_right];
        total_left += left;
        samples_left[index_left] = left;
        total_right += right;
        samples_right[index_right] = right;
        index_left = (index_left + 1) % kFilterSamples;
        index_right = (index_right + 1) % kFilterSamples;
        int16_t mean_left = total_left / kFilterSamples;
        int16_t mean_right = total_right / kFilterSamples;

        // Subtract the moving average from each channel, and repack into the
        // sample buffer.
        uint32_t offset_reg_val = (((left - mean_left) & 0xFFFF) << 16) |
                                  ((right - mean_right) & 0xFFFF);
        samples[sample++] = offset_reg_val;
        if (sample == kSamples
#if DEVICE_EXISTS_mailbox
            || !mailbox_button_pressed()
#else
#endif
        ) {
          break;
        }
      }
    }

    i2s_record_end();
#if DEVICE_EXISTS_mailbox
    mailbox_set_led(/*enabled=*/false);
#else
#endif

    Debug::log("Done recording {} samples", sample);
    int samples_captured = sample;

    // Calculate the min/max of the audio, after correcting DC offsets
    int32_t max = INT16_MIN;
    int32_t min = INT16_MAX;
    for (int i = 1; i < (samples_captured * 2); i += 2) {
      int16_t* samples_s16 = reinterpret_cast<int16_t*>(samples);
      int32_t sample = samples_s16[i];
      if (sample < min) {
        min = sample;
      }
      if (sample > max) {
        max = sample;
      }
    }

    // Calculate a scaling factor, and use this to scale the waveform
    // to a peak of 75% amplitude.
    int32_t scale_max = ((int32_t)max * 100) / ((int32_t)INT16_MAX);
    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 = 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);
      samples_s16[i] = scaled_sample;
    }

    Debug::log("Processing recorded audio...");

    // 320 x int16
    int iterations_to_process = samples_captured / 320;
    int16_t process_buffer[320];
    int16_t result_buffer[64];
    char result_buffer_encoded[ENCODE_OUT_SIZE(sizeof(result_buffer))];

    struct output_header header;
    memset(&header, 0, sizeof(header));  // NB: resume_pc = 0

    for (int i = 0; i < iterations_to_process; ++i) {
      Debug::log("Iteration {}", i);
      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];
      }
      ml_top_set_input(process_buffer, sizeof(process_buffer));

      // Start/resume kelvin
      (void) ml_top_finish_done();  // NB: reset state
      ml_top_resume_ctrl_en(header.resume_pc);

      ml_top_wait_for_finish();

      ml_top_get_output_header(&header);
      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),
             result_buffer_encoded);
      Debug::log("[sound]::ENCODER:{}",
        std::string_view(result_buffer_encoded, sizeof(result_buffer_encoded)));
    }

    Debug::log("[sound]::ENCODER: done");
    Debug::log("Done with processing.");
  }
  stats_disable();
  simulation_exit(0);
}
