summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2023-06-28 22:41:03 +0300
committergramanas <anastasis.gramm2@gmail.com>2023-06-28 22:41:03 +0300
commitf170fb058a07175e6e753f2a6d20283dc7200a88 (patch)
treee43c20efa7efe12fbe1828777474669f9ac01135
parent89e85142d0958d3e3a87fb155d698fc59eafd4c6 (diff)
downloadsynth-project-f170fb058a07175e6e753f2a6d20283dc7200a88.tar.gz
synth-project-f170fb058a07175e6e753f2a6d20283dc7200a88.tar.bz2
synth-project-f170fb058a07175e6e753f2a6d20283dc7200a88.zip
Add wavetable synthesis
-rw-r--r--src/Makefile.am4
-rw-r--r--src/midi.c3
-rw-r--r--src/synth_engine.c62
-rw-r--r--src/synth_engine.h3
-rw-r--r--src/synth_gui.c23
5 files changed, 52 insertions, 43 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index ab17d84..0ef06f4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -20,7 +20,9 @@ common_sources = adsr.c \
synth_engine.h \
synth_gui.c \
synth_gui.h \
- synth_math.h
+ synth_math.h \
+ wavetable.c \
+ wavetable.h
# -fwhole-program allows cross-file inlining, but only works when you put all
# the source files on one gcc command-line. -flto is another way to get the
diff --git a/src/midi.c b/src/midi.c
index d9955d2..8452bcc 100644
--- a/src/midi.c
+++ b/src/midi.c
@@ -27,6 +27,7 @@ void midi_decode(uint32_t msg, synth_t * synth) {
synth->midi_note[data1].velocity = (float)data2 / 127.0;
synth->midi_note[data1].elapsed = 0;
synth->midi_note[data1].active = 1;
+ synth->active = 1;
break;
case 0x0A:
printf("Aftertouch: channel=%d, note=%d, pressure=%d\n", channel, data1, data2);
@@ -144,7 +145,7 @@ init_midi(midi_t *m, synth_t *synth)
void
terminate_midi(midi_t *m)
{
- Pm_Close(m->stream);
Pt_Stop();
+ Pm_Close(m->stream);
Pm_Terminate();
}
diff --git a/src/synth_engine.c b/src/synth_engine.c
index a4d3d17..9dbf2c5 100644
--- a/src/synth_engine.c
+++ b/src/synth_engine.c
@@ -4,6 +4,7 @@
#include "filter.h"
#include "control.h"
#include "sound.h"
+#include "wavetable.h"
#include <string.h>
@@ -67,47 +68,50 @@ gen110(float f, unsigned long long phase, float x, unsigned int sample_rate)
}
float
-gen0(float f, unsigned long long phase, float x, unsigned int sample_rate)
+gen0(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- return sin_sample(1, f, phase, sample_rate);
- //return chirp(phase, f);
- /* return sqr_sample(0.1, f, 0.3, phase, sample_rate) */
- /* + sqr_sample(0.1, f * 3.0 / 2.0 , 0.5, phase, sample_rate) */
- /* + saw_sample(0.3, f, phase, sample_rate) */
- /* + sin_sample(0.1, f, phase, sample_rate) */
- /* + sin_sample(0.1, f * 5, phase, sample_rate) */
- /* /\* + sin_sample(0.1, freq * 50 * 1021, phase, sample_rate) *\/ */
- /* /\* + sin_sample(0.1, freq * 50 * 3531021, phase, sample_rate) *\/ */
- /* + sin_sample(0.1, f * 7, phase, sample_rate); */
+ return sin_sample(1, f, midi_note->elapsed, sample_rate);
+ //return chirp(midi_note->elapsed, f);
+ /* return sqr_sample(0.1, f, 0.3, midi_note->elapsed, sample_rate) */
+ /* + sqr_sample(0.1, f * 3.0 / 2.0 , 0.5, midi_note->elapsed, sample_rate) */
+ /* + saw_sample(0.3, f, midi_note->elapsed, sample_rate) */
+ /* + sin_sample(0.1, f, midi_note->elapsed, sample_rate) */
+ /* + sin_sample(0.1, f * 5, midi_note->elapsed, sample_rate) */
+ /* /\* + sin_sample(0.1, freq * 50 * 1021, midi_note->elapsed, sample_rate) *\/ */
+ /* /\* + sin_sample(0.1, freq * 50 * 3531021, midi_note->elapsed, sample_rate) *\/ */
+ /* + sin_sample(0.1, f * 7, midi_note->elapsed, sample_rate); */
}
float
-gen1(float f, unsigned long long phase, float x, unsigned int sample_rate)
+gen1(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- //return saw_sample(1, f, phase, sample_rate);
- return sawX_sample(0.5, f, 5, phase, sample_rate)
- + saw_sample(0.3, 2 * f / 5, phase, sample_rate)
- + sin_sample(0.2, f * 5.0 / 7.0 , phase, sample_rate);
+ //return saw_sample(1, f, midi_note->elapsed, sample_rate);
+ return sawX_sample(0.5, f, 5, midi_note->elapsed, sample_rate)
+ + saw_sample(0.3, 2 * f / 5, midi_note->elapsed, sample_rate)
+ + sin_sample(0.2, f * 5.0 / 7.0 , midi_note->elapsed, sample_rate);
}
float
-gen2(float f, unsigned long long phase, float x, unsigned int sample_rate)
+gen2(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- /* return sin_sample(0.5, f * sqrt(2) , phase, sample_rate) */
- /* + sin_sample(0.5, f, phase, sample_rate); */
+ /* return sin_sample(0.5, f * sqrt(2) , midi_note->elapsed, sample_rate) */
+ /* + sin_sample(0.5, f, midi_note->elapsed, sample_rate); */
- return sawX_sample(1, f, 15, phase, sample_rate);
+ return sawX_sample(1, f, 15, midi_note->elapsed, sample_rate);
}
float
-gen3(float f, unsigned long long phase, float x, unsigned int sample_rate)
+gen3(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- return sqr_sample(1, f, .5, phase, sample_rate);
- /* return sawX_sample(0.7, f, 5, phase, sample_rate) */
- /* + sin_sample(0.3, 4.0/17.0*f, phase, sample_rate); */
- /* return saw_sample(0.5, f * (1 + sqrt(5)) / 2, phase, sample_rate) */
- /* + sin_sample(0.3, f * x, phase, sample_rate) */
- /* + sqr_sample(0.2, f * x, 0.2 * x * x, phase, sample_rate); */
+ //return sqr_sample(1, f, .5, midi_note->elapsed, sample_rate);
+
+ return wvt_next(wvt_saw, f, sample_rate, &midi_note->wvt_index);
+
+ /* return sawX_sample(0.7, f, 5, midi_note->elapsed, sample_rate) */
+ /* + sin_sample(0.3, 4.0/17.0*f, midi_note->elapsed, sample_rate); */
+ /* return saw_sample(0.5, f * (1 + sqrt(5)) / 2, midi_note->elapsed, sample_rate) */
+ /* + sin_sample(0.3, f * x, midi_note->elapsed, sample_rate) */
+ /* + sqr_sample(0.2, f * x, 0.2 * x * x, midi_note->elapsed, sample_rate); */
}
float
@@ -133,6 +137,7 @@ notes_active(synth_t *synth)
synth->midi_note[i].channel = -1;
synth->midi_note[i].noteOn = -1;
synth->midi_note[i].noteOff = -1;
+ synth->midi_note[i].wvt_index = 0;
synth->midi_note[i].velocity = -1;
synth->midi_note[i].elapsed = -1;
synth->midi_note[i].active = 0;
@@ -178,7 +183,7 @@ make_sample(void *synthData, unsigned int sample_rate, int frame)
float targ_freq_with_repitch = synth->midi_note[i].freq * cc_iget(&synth->cc_pitch, frame, FRAMES_PER_BUFFER);
float synth_sample = synth->gen[synth->geni](targ_freq,
- synth->midi_note[i].elapsed,
+ &synth->midi_note[i],
synth->x,
sample_rate);
@@ -460,6 +465,7 @@ init_synth(synth_t * synth)
synth->fff2 = create_bw_band_stop_filter(8, SAMPLE_RATE, 15000, 22000);
init_sound(synth, sound_gen);
+ wvt_init();
}
void
diff --git a/src/synth_engine.h b/src/synth_engine.h
index e2e91fd..a1f3d4a 100644
--- a/src/synth_engine.h
+++ b/src/synth_engine.h
@@ -38,6 +38,7 @@ typedef struct midi_note_t {
PaTime noteOn;
PaTime noteOff;
float velocity; // normalized
+ size_t wvt_index;
unsigned long long elapsed;
adsr_t * adsr;
int active;
@@ -80,7 +81,7 @@ typedef struct {
int modifiers[16];
int modi;
- float (*gen[4]) (float freq, unsigned long long phase, float x, unsigned int sample_rate);
+ float (*gen[4]) (float freq, midi_note_t * midi_note, float x, unsigned int sample_rate);
int geni;
float cutoff;
diff --git a/src/synth_gui.c b/src/synth_gui.c
index d39995b..ee4ae05 100644
--- a/src/synth_gui.c
+++ b/src/synth_gui.c
@@ -14,18 +14,17 @@ keyboard(void *synthData, PaStream *stream)
for (int i = 0; keys[i]; i++) {
if (IsKeyPressed(keys[i])) {
- note = notes[i % 12][(synth->octave + (i / 12)) % 8];
- if (note) {
- //printf("Note On : %s[%d] %fHz\n", int_to_note(i % 12), (synth->octave + (i / 12)) % 8, note);
- synth->midi_note[i].freq = 16.35160 * pow(2, (synth->octave + i / 12.0)); //notes[i % 12][(synth->octave + (i / 12)) % 8];
- //synth->midi_note[i].freq = notes[i % 12][(synth->octave + (i / 12)) % 8];
- synth->midi_note[i].channel = -1;
- synth->midi_note[i].noteOn = Pa_GetStreamTime(synth->stream);
- synth->midi_note[i].noteOff = 0;
- synth->midi_note[i].velocity = 1.0;
- synth->midi_note[i].elapsed = 0;
- synth->midi_note[i].active = 1;
- }
+ //printf("Note On : %s[%d] %fHz\n", int_to_note(i % 12), (synth->octave + (i / 12)) % 8, note);
+ synth->midi_note[i].freq = 16.35160 * pow(2, (synth->octave + i / 12.0));
+ //synth->midi_note[i].freq = notes[i % 12][(synth->octave + (i / 12)) % 8];
+ synth->midi_note[i].channel = -1;
+ synth->midi_note[i].noteOn = Pa_GetStreamTime(synth->stream);
+ synth->midi_note[i].noteOff = 0;
+ synth->midi_note[i].velocity = 1.0;
+ synth->midi_note[i].elapsed = 0;
+ synth->midi_note[i].active = 1;
+ //synth->adsr.elapsed = 0;
+ synth->active = 1;
}
}
for (int i = 0; keys[i]; i++) {