// BLOCK LEN 1 und MAX_FIR_COEFFS 64 werden vom Compiler mitgegeben

#include <stdio.h>
#include <stdint.h>
#include "signal_processing/include/signal_path.h"

// Register und Bitmasken f�r Interrupts zwischen ARM und LPDSP Prozessor
#define CSS_CMD 0xC00004 
#define CSS_CMD_0 (1<<0)
#define CSS_CMD_1 (1<<1)

// Shared Memory von ARM und DSP definieren
#define INPUT_PORT0_ADD 0x800000  // Feste Adressen f�r Eingangsdaten im Shared Memory
#define OUTPUT_PORT_ADD (INPUT_PORT0_ADD + 16) // Feste Adressen f�r Ausgangsdatensdaten im Shared Memory, 16 Byte von Eingangsadresse Weg

// Structs anlegen f�r die Signalpfade - hier werden Konfigurationen abgelegt(signal_path.h)
static SingleSignalPath corrupted_signal;
static SingleSignalPath reference_noise_signal;

static volatile int16_t chess_storage(DMB:INPUT_PORT0_ADD) input_port[4]; //Array mit 4x16 Bit Eintr�gen auf 2x32 Bit Registern - nur die ersten 2 werden genutzt
static volatile int16_t chess_storage(DMB:OUTPUT_PORT_ADD) output_port[4]; //Array mit 4x16 Bit Eintr�gen auf 2x32 Bit Registern - alle werden genutzt
static volatile int16_t chess_storage(DMB) *input_pointer_0;
static volatile int16_t chess_storage(DMB) *input_pointer_1;
static volatile int16_t chess_storage(DMB) *output_pointer;
static volatile int16_t chess_storage(DMB) *sample_pointer;
static volatile int16_t chess_storage(DMB) sample;  //Speicherplatz f�r Ergebnis der calc()-Funktion

//void isr0() ist eine Interrupt Service Routine Funktion, welche als C Funktion deklariert wird
// property (isr) ist Chess Compiler spezifisch und kennzeichnet eine Funktion als Interrupt Service Routine
//wird Interrupt getriggert, wird action_required auf 1 gesetzt - etwas muss dannpassieren
extern "C" void isr0() property (isr) {
	action_required = 1;
	}

int main(void) {
    // Enum, welcher den Ausgabemodus definiert - wird in calc()-Funktion verwendet
    static OutputMode mode = OUTPUT_MODE_FIR_LMS;
    // Biquad Filter f�r C-Sensor und Acc-Sensor anlegen
    // Alle 0 bis auf b[0] -> einfacher Gain auf 0,75
    double b0[5]={0.75, 0., 0., 0., 0.};
    double b1[5]={0.75, 0., 0., 0., 0.};
    int coefficients = MAX_FIR_COEFFS; // 64 Koeffizienten f�r ANR

    // Signale initialisieren, oben angelegte Structs mit Parametern f�llen
    init(
        &corrupted_signal, &reference_noise_signal,   //Signal-Structs
        b0,     // Biqquad Koeffizienten C-Sensor
        b1,     // Biqquad Koeffizienten Acc-Sensor  
        2,      // Sample Delay C-Sensor
        2,     // Sample Delay Acc-Sensor
        0.9,    //Gewichtung C-Sensor
        0.9,    //Gewichtung Acc-Sensor
        0.01,   // Mu
        coefficients // Anzahl Filterkoeffizienten
    );

    FILE *fp1 = fopen("./test/testdata/input/chirp_disturber.txt", "r");
    FILE *fp2 = fopen("./test/testdata/input/disturber.txt", "r");
    FILE *fp3 = fopen("./test/testdata/output/out_simulated.txt", "w");

    int d0, d1;

    while (!(feof(fp1) || feof(fp2))){
        for (int i=0; i<BLOCK_LEN; i++){
            fscanf(fp1, "%d", &d0); //load blocks
            fscanf(fp2, "%d", &d1);
            input_port[i] = (int16_t) d0;
            input_port[i+1] = (int16_t) d1;
        }
        calc(
            &corrupted_signal, &reference_noise_signal, mode, &input_port[0], &input_port[1], output_port);
        for (int i=0; i<BLOCK_LEN; i++){
            fprintf(fp3, "%d\n", output_port[i]);
        }
    }
    fclose(fp1);
    fclose(fp2);
    fclose(fp3);
}
