#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) { .n=0 }, NULL } typedef union { /* the typedef for NUMT is below, so I cannot use that alias. */ double n; 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 unsigned long LENT; typedef double NUMT; typedef NUMT Volume; typedef NUMT Samples; typedef NUMT Hertz; typedef NUMT Seconds; typedef NUMT Pulse; typedef NUMT Beats; typedef NUMT Semitones; typedef Pulse *Wave; 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