diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/osc.c | 2 | ||||
-rw-r--r-- | src/osc.h | 1 | ||||
-rw-r--r-- | src/osc_digisaw.c | 45 | ||||
-rw-r--r-- | src/osc_saw.c | 2 | ||||
-rw-r--r-- | src/osc_sound.c | 2 | ||||
-rw-r--r-- | src/osc_tri.c | 2 | ||||
-rw-r--r-- | src/synth_engine.c | 60 | ||||
-rw-r--r-- | src/synth_gui.c | 94 |
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 \ @@ -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; */ @@ -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(); //---------------------------------------------------------------------------------- |