/* date = July 17th 2021 7:52 pm */

#ifndef AUDIO_GEN_H
#define AUDIO_GEN_H

////////////////////////////////
// TODO(allen): Notes, Unfinished Issues, Etc.
// [ ] Do we want a 12tet half step as a constant?
//     Seems like it might make more sense to bundle this
//     with some kind of notion of "scale information"
// [ ] Same idea as above but with all those hand written
//     scale constants (kind of a different problem, but it still
//     hasn't been deeply thought through).
//     [ ] If we do want to keep these, what's a good naming scheme?
// [ ] Resampling (change of rate)

////////////////////////////////
// NOTE(allen): Audio Generation Constants

global F32 audgen_silent_db = -40.f;
global F32 audgen_half_step = 0.083333333f; // 2^(1/12)

////////////////////////////////
// NOTE(allen): Audio Generation Types

typedef struct AUDGEN_Rate{
  F32 sample_per_second;
  F32 delta_t;
} AUDGEN_Rate;

////////////////////////////////
// NOTE(allen): Audio Generation Decibel Math

function F32 audgen_mul_from_decibel(F32 db);

////////////////////////////////
// NOTE(allen): Audio Generation Rate

function AUDGEN_Rate audgen_rate(F32 sample_per_second);

function U64   audgen_i_from_t(F32 sample_per_second, F32 t);

////////////////////////////////
// NOTE(allen): Audio Generation Basic Arithmetic

function void audgen_add_in_place(F32 *dst, F32 *src, U64 sample_count);
function void audgen_scalar_mul_in_place(F32 scalar, F32 *dst, U64 sample_count);

////////////////////////////////
// NOTE(allen): Audio Generation Filters

// low pass:  Y = (1 - alpha)*[-1]Y + alpha*X
// high pass: Y = alpha*[-1]Y + alpha*X - alpha*[-1]X

function void audgen_low_pass_in_place(F32 alpha, F32 *dst, U64 sample_count);
function void audgen_high_pass_in_place(F32 alpha, F32 *dst, U64 sample_count);

function F32  audgen_low_pass_alpha(F32 delta_t, F32 freq);
function F32  audgen_high_pass_alpha(F32 delta_t, F32 freq);

#endif //AUDIO_GEN_H
