From 6c358a842baaf6d211a5c8c1717d815e7813ed96 Mon Sep 17 00:00:00 2001 From: JSDurand Date: Sun, 11 Jul 2021 18:45:38 +0800 Subject: First commit Now I have a kind of piano like instrument. A violin-like instrument is being constructed. --- util.h | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 util.h (limited to 'util.h') diff --git a/util.h b/util.h new file mode 100644 index 0000000..700a8bf --- /dev/null +++ b/util.h @@ -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 -- cgit v1.2.3-18-g5258