summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am1
-rw-r--r--src/osc.c2
-rw-r--r--src/osc.h1
-rw-r--r--src/osc_digisaw.c45
-rw-r--r--src/osc_saw.c2
-rw-r--r--src/osc_sound.c2
-rw-r--r--src/osc_tri.c2
-rw-r--r--src/synth_engine.c60
-rw-r--r--src/synth_gui.c94
9 files changed, 143 insertions, 66 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 77b275c..933f4df 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -17,6 +17,7 @@ common_sources = adsr.c \
osc.h \
osc_tri.c \
osc_sin.c \
+ osc_digisaw.c \
osc_saw.c \
osc_weird.c \
osc_sound.c \
diff --git a/src/osc.c b/src/osc.c
index 295c83d..384f002 100644
--- a/src/osc.c
+++ b/src/osc.c
@@ -78,7 +78,7 @@ osc_load_wav(osc_t * osc, const char * path)
osc->end = fileInfo.frames;
osc->data = (float *) malloc(sizeof(float) * fileInfo.frames);
- // Read the WAV file into the buffer
+ // Read the WAV file into the buffer
numSamplesRead = sf_readf_float(file, osc->data, fileInfo.frames);
/* float max = -1000; */
diff --git a/src/osc.h b/src/osc.h
index 7fd0303..0dc7b81 100644
--- a/src/osc.h
+++ b/src/osc.h
@@ -95,5 +95,6 @@ OSC_COMMON_H(sin)
OSC_COMMON_H(weird)
OSC_COMMON_H(sound)
OSC_COMMON_H(saw)
+OSC_COMMON_H(digisaw)
#endif /* OSC_H */
diff --git a/src/osc_digisaw.c b/src/osc_digisaw.c
new file mode 100644
index 0000000..b71a9e3
--- /dev/null
+++ b/src/osc_digisaw.c
@@ -0,0 +1,45 @@
+#include "osc.h"
+
+osc_t OSC_digisaw = MAKE_OSC("f_digisaw", 21, WAVE);
+
+OSC_COMMON(digisaw)
+
+static float
+digisaw(int index)
+{
+ if (index == 0) return -1.0f;
+ else if (index == 1) return -0.9f;
+ else if (index == 2) return -0.8f;
+ else if (index == 3) return -0.7f;
+ else if (index == 4) return -0.6f;
+ else if (index == 5) return -0.5f;
+ else if (index == 6) return -0.4f;
+ else if (index == 7) return -0.3f;
+ else if (index == 8) return -0.2f;
+ else if (index == 9) return -0.1f;
+ else if (index == 10) return 0.0f;
+ else if (index == 11) return 0.1f;
+ else if (index == 12) return 0.2f;
+ else if (index == 13) return 0.3f;
+ else if (index == 14) return 0.4f;
+ else if (index == 15) return 0.5f;
+ else if (index == 16) return 0.6f;
+ else if (index == 17) return 0.7f;
+ else if (index == 18) return 0.8f;
+ else if (index == 19) return 0.9f;
+ else if (index == 20) return 1.0f;
+}
+
+float
+osc_digisaw(float offset)
+{
+ return osc_interpolate(offset,
+ digisaw((int)offset),
+ digisaw(osc_next_index(&OSC_digisaw, offset)));
+}
+
+float
+osc_digisaw_next(float f, float offset)
+{
+ return osc_next_offset(&OSC_digisaw, f, offset);
+}
diff --git a/src/osc_saw.c b/src/osc_saw.c
index fc31f6f..bc2fd93 100644
--- a/src/osc_saw.c
+++ b/src/osc_saw.c
@@ -4,7 +4,7 @@ osc_t OSC_saw = MAKE_OSC("f_saw", 20000, WAVE);
OSC_COMMON(saw)
-float
+static float
sawX(float sm, int offset, int len)
{
float dOutput = 0.0;
diff --git a/src/osc_sound.c b/src/osc_sound.c
index dd4eda5..e69aea2 100644
--- a/src/osc_sound.c
+++ b/src/osc_sound.c
@@ -17,9 +17,7 @@ float
osc_sound(float offset)
{
if (!OSC_sound.len) {
- //osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/test2.wav");
osc_load_wav(&OSC_sound, "/home/gramanas/code/synth-project/waves/test_lick.wav");
- /* osc_load_wav(&OSC_sound, "/mnt/data/music/samples/velvet/Drums/Kick/Kick Coldwire 1.wav"); */
}
return osc_interpolate(offset,
diff --git a/src/osc_tri.c b/src/osc_tri.c
index 8d2ef82..8dd3d41 100644
--- a/src/osc_tri.c
+++ b/src/osc_tri.c
@@ -7,7 +7,7 @@ osc_t OSC_tri = {
.len = 2,
};
-float
+static float
tri(int index)
{
if (index == 0) return -1.0f;
diff --git a/src/synth_engine.c b/src/synth_engine.c
index 8fc8221..4a4fd03 100644
--- a/src/synth_engine.c
+++ b/src/synth_engine.c
@@ -49,6 +49,9 @@ gen10(float f, unsigned long long phase, float x, unsigned int sample_rate)
float
gen110(float f, unsigned long long phase, float x, unsigned int 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 a = fmodf(phase, sample_rate/f);
return a > (sample_rate/f) / 2.0f ? 0.9999f : -0.9999f;
}
@@ -56,7 +59,10 @@ gen110(float f, unsigned long long phase, float x, unsigned int sample_rate)
float
gen0(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- return sin_sample(1, f, midi_note->elapsed, sample_rate);
+ float sample = osc_sin(midi_note->wvt_index);
+ midi_note->wvt_index = osc_sin_next(f, midi_note->wvt_index);
+ return sample;
+ /* 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) */
@@ -71,49 +77,41 @@ gen0(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
float
gen1(float f, midi_note_t * midi_note, float x, unsigned int 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 sample = osc_saw(midi_note->wvt_index);
+ midi_note->wvt_index = osc_saw_next(f, midi_note->wvt_index);
+ return sample;
}
float
gen2(float f, midi_note_t * midi_note, float x, unsigned int 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, midi_note->elapsed, sample_rate);
+ float sample = osc_weird(midi_note->wvt_index);
+ midi_note->wvt_index = osc_weird_next(f, midi_note->wvt_index);
+ return sample;
}
float
gen3(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- //return sqr_sample(1, f, .5, midi_note->elapsed, sample_rate);
-
- //return wvt_next(wvt_sound, f, sample_rate, &midi_note->wvt_index);
- float sample = osc_sound(midi_note->wvt_index);
- midi_note->wvt_index = osc_sound_next(f, midi_note->wvt_index);
+ float sample = osc_tri(midi_note->wvt_index);
+ midi_note->wvt_index = osc_tri_next(f, midi_note->wvt_index);
return sample;
-
- /* 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); */
}
float
gen4(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- float sample = osc_tri(midi_note->wvt_index);
- midi_note->wvt_index = osc_tri_next(f, midi_note->wvt_index);
+ float sample = osc_sound(midi_note->wvt_index);
+ midi_note->wvt_index = osc_sound_next(f, midi_note->wvt_index);
return sample;
- //return wvt_next(wvt_tri, f, sample_rate, &midi_note->wvt_index);
}
float
gen5(float f, midi_note_t * midi_note, float x, unsigned int sample_rate)
{
- return 0.8 * wvt_next(wvt_saw, f, sample_rate, &midi_note->wvt_index) +
- .2 * sin_sample(1, f/2, midi_note->elapsed, sample_rate);
+ float sample = osc_digisaw(midi_note->wvt_index);
+ midi_note->wvt_index = osc_digisaw_next(f, midi_note->wvt_index);
+ return sample;
}
float
@@ -189,8 +187,8 @@ make_sample(void *synthData, unsigned int sample_rate, int frame)
continue;
float adsr = fix_adsr(&synth->adsr,
- synth->midi_note[i].noteOn,
- synth->midi_note[i].noteOff,
+ synth->midi_note[i].noteOn,
+ synth->midi_note[i].noteOff,
synth->midi_note[i].elapsed,
synth->midi_note[i].noteOffSample);
@@ -199,13 +197,13 @@ make_sample(void *synthData, unsigned int sample_rate, int frame)
cc_iget(&synth->cc_lfo_amp, frame, FRAMES_PER_BUFFER) *
// (1.05946309436/24.0) *
(wvt_next(wvt_tri, (wvt_next(wvt_sound, 2 * cc_iget(&synth->cc_lfo_freq, frame, FRAMES_PER_BUFFER), SAMPLE_RATE, &lfo_index) / 2.0 + 0.5) * cc_iget(&synth->cc_lfo_freq, frame, FRAMES_PER_BUFFER), SAMPLE_RATE, &synth->midi_note[i].lfo_index) / 2.0 + 0.5);
-
- float synth_sample = synth->osctri->ops->sample(synth->osctri, synth->midi_note[i].wvt_index);
- synth->midi_note[i].wvt_index = synth->osctri->ops->next(synth->osctri, targ_freq, synth->midi_note[i].wvt_index);
- /* float synth_sample = synth->gen[synth->geni](targ_freq, */
- /* &synth->midi_note[i], */
- /* synth->x, */
- /* sample_rate); */
+
+ /* float synth_sample = synth->osctri->ops->sample(synth->osctri, synth->midi_note[i].wvt_index); */
+ /* synth->midi_note[i].wvt_index = synth->osctri->ops->next(synth->osctri, targ_freq, synth->midi_note[i].wvt_index); */
+ float synth_sample = synth->gen[synth->geni](targ_freq,
+ &synth->midi_note[i],
+ synth->x,
+ sample_rate);
sample += 0.2 * rms * adsr * synth_sample;
}
diff --git a/src/synth_gui.c b/src/synth_gui.c
index ca1acc9..46ec71f 100644
--- a/src/synth_gui.c
+++ b/src/synth_gui.c
@@ -4,6 +4,53 @@
//#include "raylib.h"
void
+draw_text(synth_t * synth, Font f, int x, int y)
+{
+ char buf[64];
+ int count = 0;
+ float text_size = 10;
+ int offset = 12;
+
+ snprintf(buf, sizeof buf, "lfo freq %.4f", synth->cc_lfo_freq.value);
+ DrawText(buf, x, y + offset * count++, text_size, GRAY);
+ snprintf(buf, sizeof buf, "lfo amp %.4f", synth->cc_lfo_amp.value);
+ DrawText(buf, x, y + offset * count++, text_size, GRAY);
+ snprintf(buf, sizeof buf, "filter reso %.4f", synth->cc_resonance.value);
+ DrawText(buf, x, y + offset * count++, text_size, GRAY);
+ snprintf(buf, sizeof buf, "filter cutoff %.1f", synth->cc_cutoff.value);
+ DrawText(buf, x, y + offset * count++, text_size, GRAY);
+ snprintf(buf, sizeof buf, "extra pitch %.4f", synth->cc_pitch.value);
+ DrawText(buf, x, y + offset * count++, text_size, GRAY);
+
+ DrawRectangleLines(x - 6, y - 3, 120, 3 + (count * offset) + 3, GRAY);
+}
+
+void
+mouse(void *synthData, PaStream *stream)
+{
+ synth_t * synth = (synth_t *)synthData;
+ float m = GetMouseWheelMove();
+ int x = 0;
+ if (m < 0) x = -1;
+ else if (m > 0) x = 1;
+ int y = GetMouseY();
+
+ if (x) {
+ if (y > 20 && y <= 32) {
+ cc_step(&synth->cc_lfo_freq, x);
+ } else if (y > 32 && y <= 44) {
+ cc_step(&synth->cc_lfo_amp, x);
+ } else if (y > 44 && y <= 56) {
+ cc_step(&synth->cc_resonance, x);
+ } else if (y > 56 && y <= 68) {
+ cc_step(&synth->cc_cutoff, x);
+ } else if (y > 68 && y <= 80) {
+ cc_step(&synth->cc_pitch, x);
+ }
+ }
+}
+
+void
keyboard(void *synthData, PaStream *stream)
{
synth_t * synth = (synth_t *)synthData;
@@ -104,7 +151,7 @@ keyboard(void *synthData, PaStream *stream)
}
void
-draw_adsr_sliders(synth_t * synth, int x, int y, int width, int height, int offset)
+draw_bars(synth_t * synth, int x, int y, int width, int height, int offset)
{
char buf[64];
int count = 0;
@@ -127,6 +174,8 @@ draw_adsr_sliders(synth_t * synth, int x, int y, int width, int height, int offs
synth->lfo.freq = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "lfo freq: ", buf, synth->lfo.freq , 0.001f, 10.0f);
snprintf(buf, sizeof buf, "%.3f", synth->lfo.amp);
synth->lfo.amp = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "lfo amp: ", buf, synth->lfo.amp , 0.0f, 0.93f);
+ snprintf(buf, sizeof buf, "%.3f", synth->gain);
+ synth->gain = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "gain: ", buf, synth->gain , 0.0f, 2.0f);
}
void
@@ -161,18 +210,20 @@ draw_signals(synth_t * synth, int x, int y, int width, int height)
}
}
+#include "raystyle.h"
void
-rayrun(void *synthData)
-{
+rayrun(void *synthData){
synth_t * synth = (synth_t *)synthData;
PaTime current_time = 0;
PaTime prev_time = 0;
- InitWindow(WIDTH, HEIGHT, "Raylib synth");
+ InitWindow(WIDTH, HEIGHT, "Raylib synth");
+ Font f = LoadFont("/usr/share/fonts/TTF/DejaVuSans.ttf");
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
while (!WindowShouldClose()) {
keyboard(synth, synth->stream);
+ mouse(synth, synth->stream);
int prec = 100000;
if (IsKeyPressed(KEY_ENTER)) {
@@ -187,31 +238,15 @@ rayrun(void *synthData)
// GUI
char buf[64];
- draw_adsr_sliders(synth, 30, 20, 256, 20, 4);
-
+ draw_bars(synth, 33, 20, 256, 20, 4);
+ draw_text(synth, f, WIDTH / 2 - 108, 20);
/* if ( GuiButton((Rectangle){ WIDTH / 2 - 108, 150 - 42 - 6 - 6, 216, 6 }, "")) { */
/* synth->freq_offset = 0; */
/* } */
- snprintf(buf, sizeof buf, "extra pitch %.4f", synth->cc_pitch.value);
- DrawText(buf, WIDTH / 2 - 108, 150 - 82, 20, LIGHTGRAY);
- snprintf(buf, sizeof buf, "filter cutoff %.1f", synth->cc_cutoff.value);
- DrawText(buf, WIDTH / 2 - 108, 150 - 42, 20, LIGHTGRAY);
- snprintf(buf, sizeof buf, "filter reso %.4f", synth->cc_resonance.value);
- DrawText(buf, WIDTH / 2 - 108, 150 - 62, 20, LIGHTGRAY);
- snprintf(buf, sizeof buf, "lfo amp %.4f", synth->cc_lfo_amp.value);
- DrawText(buf, WIDTH / 2 - 108, 150 - 22, 20, LIGHTGRAY);
- snprintf(buf, sizeof buf, "lfo freq %.4f", synth->cc_lfo_freq.value);
- DrawText(buf, WIDTH / 2 - 108, 150 - 102, 20, LIGHTGRAY);
/* snprintf(buf, sizeof buf, "freq offset %.1f", synth->freq_offset); */
/* DrawText(buf, WIDTH / 2 - 108, 150 - 42, 20, LIGHTGRAY); */
- /* synth->freq_offset = GuiSlider((Rectangle){ WIDTH / 2 - 108, 150 - 42, 216, 24 }, "fine", buf, synth->freq_offset , -20.0f, 20.0f); */
-
- if ( GuiButton((Rectangle){ WIDTH / 2 - 108, 150 - 6 - 6, 216, 6 }, "")) {
- synth->gain = 1;
- }
- snprintf(buf, sizeof buf, "%.1f", synth->gain);
- synth->gain = GuiSlider((Rectangle){ WIDTH / 2 - 108, 150, 216, 24 }, "gain", buf, synth->gain , 0.0f, 2.0f);
+ /* synth->freq_offset = GuiSlider((Rectangle){ WIDTH / 2 - 108, 150 - 42, 216, 24 }, "fine", buf, synth->freq_offset , -20.0f, 20.0f); */
if ( GuiButton((Rectangle){ WIDTH / 2 - 108, 150 - 6 - 6 + 42, 216, 6 }, "")) {
synth->x = 1;
@@ -219,9 +254,9 @@ rayrun(void *synthData)
snprintf(buf, sizeof buf, "%.1f", synth->x);
synth->x = GuiSlider((Rectangle){ WIDTH / 2 - 108, 150 + 42, 216, 24 }, "x", buf, synth->x , 0.0f, 2.0f);
- synth->multi = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50, 100, 24 }, "!MULTI!", synth->multi);
- synth->filter = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50 + 24 + 6, 100, 24 }, "FILTER", synth->filter);
- synth->poly = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50 + 24 + 6 + 24 + 6, 100, 24 }, "POLY", synth->poly);
+ //synth->multi = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50, 100, 24 }, "!MULTI!", synth->multi);
+ synth->filter = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50 , 100, 24 }, "FILTER", synth->filter);
+ //synth->poly = GuiToggle((Rectangle){ WIDTH - 100 - 50 - 100 - 50 , 50 + 24 + 6 + 24 + 6, 100, 24 }, "POLY", synth->poly);
GuiSpinner((Rectangle){ WIDTH - 100 - 50 , 50, 100, 24 }, "oct: ", &(synth->octave), 0, 7, 0);
snprintf(buf, sizeof buf, "generator %d --> ", synth->geni);
@@ -229,14 +264,13 @@ rayrun(void *synthData)
synth->clamp = GuiToggle((Rectangle){ WIDTH - 100 - 50, 50 + 24 + 6 + 24 + 6, 100, 24 }, "clamp", synth->clamp);
-
// signals
draw_signals(synth, 20, 390, WIDTH - 2*20, 200);
//DrawText("THE SYNTH!!!!!!!!!!!!!!!!!!1", WIDTH / 2 - 100, 50, 20, LIGHTGRAY);
- DrawText("KEYBOARD: Q .. ] TOGGLE MULTI: ENTER", WIDTH / 2 -300, HEIGHT - 300 - 50, 20, LIGHTGRAY);
- snprintf(buf, sizeof buf, "%f stream time: %f", synth->viz.wave[0], Pa_GetStreamTime(synth->stream));
- DrawText(buf, WIDTH / 2 -300, HEIGHT - 300, 20, LIGHTGRAY);
+ DrawText("KEYBOARD: Q .. ]", WIDTH / 2 -300, HEIGHT - 300 - 50, 20, LIGHTGRAY);
+ snprintf(buf, sizeof buf, "stream time: %f", Pa_GetStreamTime(synth->stream));
+ DrawText(buf, WIDTH / 2 -300, HEIGHT - 300, 11, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------