// Copyright 2024-2025 XMOS LIMITED.
// This Software is subject to the terms of the XMOS Public Licence: Version 1.

#include <xcore/assert.h>
#include <xua.h>
#include <xua_audiohub.h>
#include <stdint.h>
#include <stages/adsp_pipeline.h>
#include <adsp_generated_auto.h>
#include "dsp_control.h"

static adsp_pipeline_t * m_dsp;

// Fills an array of points to point to the corresponding element
// of an input array.
static void arr_to_pointer(int32_t ** pointer, unsigned * arr, int n) {
  for(int i = 0; i < n; ++i) {
    pointer[i] = &((int32_t *)arr)[i];
  }
}

// Standard lib_xua callback function.
void UserBufferManagement(unsigned* sampsFromUsbToAudio, unsigned* sampsFromAudioToUsb) {
  xassert(NULL != m_dsp);

  int32_t * dsp_input[NUM_USB_CHAN_OUT + I2S_CHANS_ADC];
  arr_to_pointer(&dsp_input[0], sampsFromUsbToAudio, NUM_USB_CHAN_OUT);
  arr_to_pointer(&dsp_input[NUM_USB_CHAN_OUT], sampsFromAudioToUsb, I2S_CHANS_ADC);
  adsp_pipeline_source(m_dsp, dsp_input);

  int32_t* dsp_output[NUM_USB_CHAN_IN + I2S_CHANS_DAC];
  arr_to_pointer(&dsp_output[0], sampsFromAudioToUsb, NUM_USB_CHAN_IN);
  arr_to_pointer(&dsp_output[NUM_USB_CHAN_IN], sampsFromUsbToAudio, I2S_CHANS_DAC);
  adsp_pipeline_sink(m_dsp, dsp_output);
}

// start dsp_thread
void dsp_thread(chanend_t c_control) {
  // Initialise the DSP instance and enter the generated DSP main function.
  // This will never return.
  m_dsp = adsp_auto_pipeline_init();
  adsp_controller_t control;
  adsp_controller_init(&control, m_dsp);

  PAR_JOBS(
    PJOB(adsp_auto_pipeline_main, (m_dsp)),
    PJOB(dsp_control_thread, (c_control, &control))
  );
}
