diff options
author | JSDurand <mmemmew@gmail.com> | 2021-07-11 18:45:38 +0800 |
---|---|---|
committer | JSDurand <mmemmew@gmail.com> | 2021-07-11 18:45:38 +0800 |
commit | 6c358a842baaf6d211a5c8c1717d815e7813ed96 (patch) | |
tree | c78122d49e75a540a4f6054b224a90738b554606 /util.h |
First commit
Now I have a kind of piano like instrument. A violin-like instrument
is being constructed.
Diffstat (limited to 'util.h')
-rw-r--r-- | util.h | 126 |
1 files changed, 126 insertions, 0 deletions
@@ -0,0 +1,126 @@ +#ifndef UTIL_H +#define UTIL_H + +/* Mostly types, constants, and macros */ + +/* A simple singly linked list */ + +/* Push a node to the singly linked list. */ +#define PUSH_NODE(NUM_VAR, POINTER, CUR, VALUE, TYPE) { \ + (NUM_VAR)++; \ + if (NUM_VAR > 1) { \ + (POINTER) = MYALLOC(Node_t, 1); \ + *(POINTER) = (CUR); \ + (CUR) = (Node_t) { (Node_v) { .TYPE=(VALUE) }, (POINTER) }; \ + } else { \ + (CUR) = (Node_t) { (Node_v) { .TYPE=(VALUE) }, NULL }; \ + } \ + } + +/* Pop one node out of the singly linked list. */ +#define POP_NODE(NUM_VAR, X, CUR, NEXT, TYPE) { \ + (NUM_VAR)--; \ + X = CUR.value.TYPE; \ + if (CUR.next) { \ + NEXT = *(CUR.next); \ + free(CUR.next); \ + CUR = NEXT; \ + } \ + } + +/* An empty node. */ +#define EMPTY_NODE (Node_t) { (Node_v) { .f=0 }, NULL } + +typedef union { + float f; + void *v; /* very evil */ +} Node_v; + +typedef struct Node { + Node_v value; + struct Node *next; +} Node_t; + +/* macros */ + +#define MYALLOC(X, Y) ((X *) malloc(sizeof(X)*Y)) /* The most useful macro perhaps */ + +/* Constant macros */ + +#define SAMPLE_RATE 44100.0f +#define DEFAULT_OUTPUT_NAME "output.mp3" +#define STDP 440.0f +/* I don't want to use a global variable for this constant. */ +#define STD_BASE 1.059463094359295f +/* TODO: Set Volume, and other settings in the sheet. */ +/* These can now be changed in the sheet. */ +#define BPM 120.0f +#define BEAT_DUR (60.0f / BPM) + +/* Frequency modulation */ + +#define FM_FREQUENCY 2.0f +#define FM_AMP 0.02f + +/* For ADSR */ +#define ATTACK_P 0.01f +#define DECAY_P 0.495f +#define RELEASE_P 0.49f +#define SUSTAIN_P (1.0f-(ATTACK_P+DECAY_P+RELEASE_P)) +#define SUSTAIN_LEVEL 0.7f + +/* attribute macros */ + +#define AHC_ATTR __attribute__((__always_inline__, __hot__, __const__)) +#define AH_ATTR __attribute__((__always_inline__, __hot__)) +#define HC_ATTR __attribute__((__hot__, __const__)) +#define H_ATTR __attribute__((__hot__)) +#define UNUSED __attribute__((__unused__)) +#define U_ATTR UNUSED + +#define D_ATTR(X) __attribute__((__unused__, __deprecated__("This is deprecated.\n" \ + "Please use " X \ + " instead"))) + +#define UC_ATTR __attribute__((__unused__, __const__)) +#define UH_ATTR __attribute__((__unused__, __hot__)) +#define UHA_ATTR __attribute__((__unused__, __hot__, __always_inline__)) + +/* types */ + +typedef float Volume; +typedef float Samples; +typedef float Hertz; +typedef float Seconds; +typedef float Pulse; +typedef float Beats; +typedef float Semitones; +typedef Pulse *Wave; + +typedef unsigned long LENT; + +typedef struct { + Wave w; + LENT n; +} WaveFrag; + +/* supported instrument types */ + +typedef enum { + PIANO, + DRUMKICK +} InstrumentTypes; + +/* some helper functions */ + +U_ATTR LENT max(LENT a, LENT b); + +U_ATTR LENT min(LENT a, LENT b); + +UNUSED long read_entire_file(const char *file_name, char **str); + +U_ATTR WaveFrag mix_waves(WaveFrag *frags, LENT len); + +HC_ATTR Hertz stoh(const Semitones st); + +#endif |