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
|
#ifndef OSC_H
#define OSC_H
#include <math.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
/**
* The main idea of the osc is the following:
* The root of the sound is a periodic wave function.
* This can be a stored period of a wave in a wavetable
* or a function like sin(). In order to play a sound with
* the wave an external float offset is kept that points to the
* next sample, a function is provided to advance this offset
* a calucalted step amount, depending on the desired frequency.
* Linear interpolation is used so that a float offset can work
* and provide autosmoothing.
*/
enum osc_type {
WAVE,
SAMPLE
};
struct osc_t;
struct osc_ops {
void (*set_start)(struct osc_t *, long);
void (*set_end) (struct osc_t *, long);
void (*set_len) (struct osc_t *, long);
float (*sample) (struct osc_t *, float);
float (*next) (struct osc_t *, float, float);
};
typedef struct osc_t {
char name[16];
float * data;
long len;
long start;
long end;
enum osc_type type;
const struct osc_ops * ops;
} osc_t;
#define MAKE_OSC(_name, _len, _type) { \
.name = _name, \
.data = 0, \
.len = _len, \
.start = 0, \
.end = _len, \
.type = _type, \
};
/* Initializes the wavetables and functions for the oscilators */
void init_osc();
float osc_interpolate(float offset, float start, float end);
float osc_next_offset(osc_t * osc, float f, float offset);
int osc_next_index(osc_t * osc, float offset);
int osc_load_wav(osc_t * osc, const char * path);
osc_t * make_tri(const char * name);
/***************/
/* OSCILATORS */
/***************/
// function prototypes common for all oscs
#define OSC_COMMON_H(osc) \
void \
set_##osc##_start(long start); \
void \
set_##osc##_end(long end); \
void \
set_##osc##_len(long len); \
float \
osc_##osc(float offset); \
float \
osc_##osc##_next(float f, float offset);
// function definitions common for all oscs
#define OSC_COMMON(osc) \
void \
set_##osc##_start(long start) \
{ OSC_##osc.start = start; } \
void \
set_##osc##_end(long end) \
{ OSC_##osc.end = end; } \
void \
set_##osc##_len(long len) \
{ OSC_##osc.len = len; }
OSC_COMMON_H(tri)
OSC_COMMON_H(sin)
OSC_COMMON_H(weird)
OSC_COMMON_H(sound)
OSC_COMMON_H(saw)
OSC_COMMON_H(digisaw)
#endif /* OSC_H */
|