summaryrefslogtreecommitdiff
path: root/util.h
blob: 3665ee1fc02af2c33617352f9b047963a2782dbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#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