#ifndef MR4TH_DSP_H
#define MR4TH_DSP_H

////////////////////////////////
// Signal Processing Types

typedef struct DSP_Signal{
  F32 *samples;
  U64 sample_count;
  F32 samples_per_second;
  F32 delta_t;
} DSP_Signal;

typedef struct DSP_Spectrum{
  F32 *rl;
  F32 *im;
  U64 count;
} DSP_Spectrum;

////////////////////////////////
// Signal Processing Functions

// basic signals

MR4TH_SYMBOL_STATIC DSP_Signal* dsp_new_ptr(Arena *arena, F32 *samples, U64 sample_count, F32 samples_per_second);
MR4TH_SYMBOL_STATIC DSP_Signal* dsp_new(Arena *arena, U64 sample_count, F32 samples_per_second);
MR4TH_SYMBOL_STATIC DSP_Signal* dsp_new_from_buffer(Arena *arena, BOP_Data *buffer, F32 samples_per_second);
MR4TH_SYMBOL_STATIC DSP_Signal* dsp_copy(Arena *arena, DSP_Signal *signal);

// resampling

MR4TH_SYMBOL_STATIC DSP_Signal* dsp_resample(Arena *arena, DSP_Signal *signal, F32 dst_sps);
MR4TH_SYMBOL_STATIC U64  dsp_resample_count(U64 src_count, F32 src_sps, F32 dst_sps);
MR4TH_SYMBOL_STATIC void dsp_resample_raw(F32 *dst, U64 dst_count, F32 *src, U64 src_count);

// mixing

MR4TH_SYMBOL_STATIC void        dsp_add_inplace(DSP_Signal *dst, DSP_Signal *src);
MR4TH_SYMBOL_STATIC DSP_Signal* dsp_mix2(Arena *arena, DSP_Signal *s0, F32 a0, DSP_Signal *s1, F32 a1);

// filters

MR4TH_SYMBOL_STATIC void dsp_low_pass(DSP_Signal *signal, F32 cutoff_hz);
MR4TH_SYMBOL_STATIC void dsp_low_pass_raw(F32 alpha, F32 *samples, U64 count);
MR4TH_SYMBOL_STATIC F32  dsp_low_pass_alpha(F32 rate_delta_t, F32 cutoff_hz);

MR4TH_SYMBOL_STATIC void dsp_high_pass(DSP_Signal *signal, F32 cutoff_hz);
MR4TH_SYMBOL_STATIC void dsp_high_pass_raw(F32 alpha, F32 *samples, U64 count);
MR4TH_SYMBOL_STATIC F32  dsp_high_pass_alpha(F32 rate_delta_t, F32 cutoff_hz);

// fourier transform

MR4TH_SYMBOL_STATIC void          dsp_samples_from_signal_window(DSP_Signal *signal, U64 first, U64 count, F32 **samples_out, U64 *sample_count_out);
MR4TH_SYMBOL_STATIC DSP_Spectrum* dsp_spectrum_from_samples(Arena *arena, F32 *samples, U64 sample_count, U64 count);

// decibel math

MR4TH_SYMBOL_STATIC F32 dsp_scalar_from_db(F32 db);
MR4TH_SYMBOL_STATIC F32 dsp_db_from_scalar(F32 a);

////////////////////////////////
// Serialization

MR4TH_SYMBOL_STATIC String8       dsp_spectrum_serialize(Arena *arena, DSP_Spectrum *spectrum);
MR4TH_SYMBOL_STATIC DSP_Spectrum* dsp_spectrum_deserialize(Arena *arena, String8 data);

#endif //MR4TH_DSP_H
