Browse Source

use new envelope code

vampirefrog 3 years ago
parent
commit
19f165350c
5 changed files with 49 additions and 40 deletions
  1. 2
    0
      envelope.h
  2. 37
    38
      synth.c
  3. 3
    2
      synth.h
  4. 6
    0
      voice.c
  5. 1
    0
      voice.h

+ 2
- 0
envelope.h View File

@@ -3,6 +3,8 @@
3 3
 
4 4
 #include <stdint.h>
5 5
 
6
+// Code converted to C from http://www.earlevel.com/main/2013/06/01/envelope-generators/
7
+
6 8
 struct Envelope {
7 9
 	// private
8 10
 	enum {

+ 37
- 38
synth.c View File

@@ -19,7 +19,7 @@ void synth_init(struct Synth *synth) {
19 19
 	synth->lfo_depth = 0.0;
20 20
 	sine_osc_init(&synth->lfo_osc);
21 21
 	for(int i = 0; i < SYNTH_NUM_VOICES; i++) {
22
-		synth->voices[i].synth = synth;
22
+		voice_init(&synth->voices[i], synth);
23 23
 	}
24 24
 }
25 25
 
@@ -35,7 +35,7 @@ static void synth_set_pitch(struct Synth *synth) {
35 35
 	float lfo_detune = synth->lfo_depth * sine_osc_sample(&synth->lfo_osc);
36 36
 	for(int i = 0; i < SYNTH_NUM_VOICES; i++) {
37 37
 		struct Voice *voice = &synth->voices[i];
38
-		if(voice->osc_env.state != None)
38
+		if(voice->osc_env.state != EnvNone)
39 39
 			oscillator_set_freq(&voice->osc, detune(midifreq(voice->note), voice->detune + synth->pitch_bend * synth->pitch_bend_range + lfo_detune));
40 40
 	}
41 41
 }
@@ -48,9 +48,9 @@ static void synth_spread_unison(struct Synth *synth) {
48 48
 	for(int i = 4; i < 7; i++) {
49 49
 		synth->voices[i].detune = (i - 7) * synth->unison_spread / 6.0;
50 50
 	}
51
-	for(int i = 0; i < 7; i++) {
52
-		printf("voice %d detune %f\n", i, synth->voices[i].detune);
53
-	}
51
+	// for(int i = 0; i < 7; i++) {
52
+	// 	printf("voice %d detune %f\n", i, synth->voices[i].detune);
53
+	// }
54 54
 }
55 55
 
56 56
 static void synth_spread_stereo(struct Synth *synth) {
@@ -58,9 +58,9 @@ static void synth_spread_stereo(struct Synth *synth) {
58 58
 	for(int i = 1; i <= 7; i++) {
59 59
 		synth->voices[i].pan = ((i&1) * 2 - 1) * synth->stereo_spread * ((i + 1) / 2) / 3;
60 60
 	}
61
-	for(int i = 0; i < 7; i++) {
62
-		printf("voice %d pan %f\n", i, synth->voices[i].pan);
63
-	}
61
+	// for(int i = 0; i < 7; i++) {
62
+	// 	printf("voice %d pan %f\n", i, synth->voices[i].pan);
63
+	// }
64 64
 }
65 65
 
66 66
 static void synth_note_on_monophonic(struct Synth *synth, uint8_t note, uint8_t velocity) {
@@ -71,17 +71,17 @@ static void synth_note_on_monophonic(struct Synth *synth, uint8_t note, uint8_t
71 71
 		struct Voice *voice = synth->voices + i;
72 72
 		voice->osc.phase = random();
73 73
 
74
-		voice->osc_env.attack = synth->osc_env.attack;
75
-		voice->osc_env.decay = synth->osc_env.decay;
76
-		voice->osc_env.sustain = synth->osc_env.sustain;
77
-		voice->osc_env.release = synth->osc_env.release;
74
+		envelope_set_attack_rate(&voice->osc_env, synth->osc_attack);
75
+		envelope_set_decay_rate(&voice->osc_env, synth->osc_decay);
76
+		envelope_set_sustain_level(&voice->osc_env, synth->osc_sustain);
77
+		envelope_set_release_rate(&voice->osc_env, synth->osc_release);
78 78
 
79
-		voice->filter_env.attack = synth->filter_env.attack;
80
-		voice->filter_env.decay = synth->filter_env.decay;
81
-		voice->filter_env.sustain = synth->filter_env.sustain;
82
-		voice->filter_env.release = synth->filter_env.release;
79
+		envelope_set_attack_rate(&voice->filter_env, synth->filter_attack);
80
+		envelope_set_decay_rate(&voice->filter_env, synth->filter_decay);
81
+		envelope_set_sustain_level(&voice->filter_env, synth->filter_sustain);
82
+		envelope_set_release_rate(&voice->filter_env, synth->filter_release);
83 83
 
84
-		voice_note_start(voice, note, i == 0 ? velocity : velocity / 4);
84
+		voice_note_start(voice, note, velocity);
85 85
 	}
86 86
 }
87 87
 
@@ -100,7 +100,7 @@ void synth_note_on(struct Synth *synth, uint8_t note, uint8_t velocity) {
100 100
 		uint32_t oldest_time = 0;
101 101
 		for(int i = 0; i < SYNTH_NUM_VOICES; i++) {
102 102
 			struct Voice *voice = &synth->voices[i];
103
-			if(voice->osc_env.state == None) {
103
+			if(voice->osc_env.state == EnvNone) {
104 104
 				found = voice;
105 105
 				break;
106 106
 			}
@@ -109,15 +109,16 @@ void synth_note_on(struct Synth *synth, uint8_t note, uint8_t velocity) {
109 109
 				found = voice;
110 110
 			}
111 111
 		}
112
-		found->osc_env.attack = synth->osc_env.attack;
113
-		found->osc_env.decay = synth->osc_env.decay;
114
-		found->osc_env.sustain = synth->osc_env.sustain;
115
-		found->osc_env.release = synth->osc_env.release;
116 112
 
117
-		found->filter_env.attack = synth->filter_env.attack;
118
-		found->filter_env.decay = synth->filter_env.decay;
119
-		found->filter_env.sustain = synth->filter_env.sustain;
120
-		found->filter_env.release = synth->filter_env.release;
113
+		envelope_set_attack_rate(&found->osc_env, synth->osc_attack);
114
+		envelope_set_decay_rate(&found->osc_env, synth->osc_decay);
115
+		envelope_set_sustain_level(&found->osc_env, synth->osc_sustain);
116
+		envelope_set_release_rate(&found->osc_env, synth->osc_release);
117
+
118
+		envelope_set_attack_rate(&found->filter_env, synth->filter_attack);
119
+		envelope_set_decay_rate(&found->filter_env, synth->filter_decay);
120
+		envelope_set_sustain_level(&found->filter_env, synth->filter_sustain);
121
+		envelope_set_release_rate(&found->filter_env, synth->filter_release);
121 122
 
122 123
 		voice_note_start(found, note, velocity);
123 124
 	}
@@ -141,7 +142,7 @@ void synth_note_off(struct Synth *synth, uint8_t note, uint8_t velocity) {
141 142
 	} else {
142 143
 		for(int i = 0; i < SYNTH_NUM_VOICES; i++) {
143 144
 			struct Voice *voice = synth->voices + i;
144
-			if(voice->note == note && voice->osc_env.state != None && voice->osc_env.state != Release) {
145
+			if(voice->note == note && voice->osc_env.state != EnvNone && voice->osc_env.state != EnvRelease) {
145 146
 				voice_stop(&synth->voices[i]);
146 147
 			}
147 148
 		}
@@ -155,7 +156,7 @@ void synth_render_sample(struct Synth *synth, float *out) {
155 156
 
156 157
 	for(int i = 0; i < SYNTH_NUM_VOICES; i++) {
157 158
 		struct Voice *v = &synth->voices[i];
158
-		if(v->osc_env.state == None) continue;
159
+		if(v->osc_env.state == EnvNone) continue;
159 160
 
160 161
 		float vsmpl[2];
161 162
 		voice_render_sample(v, vsmpl);
@@ -222,23 +223,21 @@ void synth_load_patch(struct Synth *s, const char *filename) {
222 223
 				if(!strcmp(tok, "lfo_freq")) {
223 224
 					sine_osc_set_freq(&s->lfo_osc, strtof(val, NULL));
224 225
 				} else if(!strcmp(tok, "osc_env.attack")) {
225
-					s->osc_env.attack = strtof(val, NULL);
226
+					s->osc_attack = strtof(val, NULL);
226 227
 				} else if(!strcmp(tok, "osc_env.decay")) {
227
-					s->osc_env.decay = strtof(val, NULL);
228
+					s->osc_decay = strtof(val, NULL);
228 229
 				} else if(!strcmp(tok, "osc_env.sustain")) {
229
-					s->osc_env.sustain = strtof(val, NULL);
230
+					s->osc_sustain = strtof(val, NULL);
230 231
 				} else if(!strcmp(tok, "osc_env.release")) {
231
-					s->osc_env.release = strtof(val, NULL);
232
+					s->osc_release = strtof(val, NULL);
232 233
 				} else if(!strcmp(tok, "filter_env.attack")) {
233
-					printf("filter_env.attack %f\n", strtof(val, NULL));
234
-					s->filter_env.attack = strtof(val, NULL);
234
+					s->filter_attack = strtof(val, NULL);
235 235
 				} else if(!strcmp(tok, "filter_env.decay")) {
236
-					printf("filter_env.decay %f\n", strtof(val, NULL));
237
-					s->filter_env.decay = strtof(val, NULL);
236
+					s->filter_decay = strtof(val, NULL);
238 237
 				} else if(!strcmp(tok, "filter_env.sustain")) {
239
-					s->filter_env.sustain = strtof(val, NULL);
238
+					s->filter_sustain = strtof(val, NULL);
240 239
 				} else if(!strcmp(tok, "filter_env.release")) {
241
-					s->filter_env.release = strtof(val, NULL);
240
+					s->filter_release = strtof(val, NULL);
242 241
 				} else if(!strcmp(tok, "filter_eg_intensity")) {
243 242
 					s->filter_eg_intensity  = strtof(val, NULL);
244 243
 				} else if(!strcmp(tok, "filter_kbd_track")) {

+ 3
- 2
synth.h View File

@@ -19,7 +19,8 @@ struct Key {
19 19
 
20 20
 struct Synth {
21 21
 	struct Voice voices[SYNTH_NUM_VOICES];
22
-	struct Envelope osc_env, filter_env;
22
+	float osc_attack, osc_decay, osc_sustain, osc_release;
23
+	float filter_attack, filter_decay, filter_sustain, filter_release;
23 24
 	float unison_spread;
24 25
 	float stereo_spread;
25 26
 	uint8_t monophonic;
@@ -29,8 +30,8 @@ struct Synth {
29 30
 	float cutoff, filter_eg_intensity, filter_kbd_track, lfo_freq;
30 31
 
31 32
 	// private
32
-	struct Key key_stack[SYNTH_NUM_VOICES];
33 33
 	struct SineOsc lfo_osc;
34
+	struct Key key_stack[SYNTH_NUM_VOICES];
34 35
 	uint8_t key_stack_size;
35 36
 	float volume, pitch_bend, lfo_depth;
36 37
 	uint32_t time;

+ 6
- 0
voice.c View File

@@ -1,5 +1,11 @@
1 1
 #include "synth.h"
2 2
 
3
+void voice_init(struct Voice *v, struct Synth *synth) {
4
+	v->synth = synth;
5
+	envelope_init(&v->osc_env);
6
+	envelope_init(&v->filter_env);
7
+}
8
+
3 9
 void voice_render_sample(struct Voice *v, float *out) {
4 10
 	//if(v->osc_env.state == None) return;
5 11
 	float amplitude = envelope_sample(&v->osc_env); // calculate based on key velocity and envelope

+ 1
- 0
voice.h View File

@@ -21,6 +21,7 @@ struct Voice {
21 21
 	struct Filter filter;
22 22
 };
23 23
 
24
+void voice_init(struct Voice *voice, struct Synth *synth);
24 25
 void voice_note_start(struct Voice *voice, uint8_t note, uint8_t velocity);
25 26
 void voice_stop(struct Voice *voice);
26 27
 void voice_render_sample(struct Voice *voice, float *out);

Loading…
Cancel
Save