summaryrefslogblamecommitdiffstats
path: root/src/synth_gui.c
blob: 46ec71fa16f8ec1ef3d4a5d87fa1d53a42d3073d (plain) (tree)
1
2
3
4
5
6




                             
    














































                                                                              









                                                                                                                                                                                                               








                                                                                                     
      

                                



                                 
                                                                    
                                                                      
                                                           

     






















                                                                    


                                         















                                           


                                         















                                           


                                         

     


    
                                                                           




                                                   


                                                                                                                                            
                                                   
                                                                                                                                        
                                                   
                                                                                                                                      
                                                   
                                                                                                                                         

                                                                                                                                              

                                                                                                                                                        


                                                                                                                                                       
                                                                                                                                                  

                                                                                                                                     









                                                                                                                        
 
                                       
                                                                                                 
   
 




                                                                                                                                    
 


                                                                                                                                                                                                                                                                  
                                       



                                          
                                                                                                                                                                                                                                        
     


   
                     
    
                        



                                         

                                                           


                                                                                
                                   
                                








                                                                                        
                           



                 

                                             
 


                                                                                         

                                                                            
                                                                                                                                             




                                                                                   
                                                                                                             
 


                                                                                                                               


                                                                                                  
                                                                                                     


                                                                                                                    


                                                    
                                                                                   


                                                                                   



                                                                                        
                                                   





                                                             
#include "synth_gui.h"
#define RAYGUI_IMPLEMENTATION
#include "raygui.h"
//#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;

  int keys[] = {KEY_Q, KEY_TWO, KEY_W, KEY_THREE, KEY_E, KEY_R, KEY_FIVE, KEY_T, KEY_SIX, KEY_Y, KEY_SEVEN, KEY_U, KEY_I, KEY_NINE, KEY_O, KEY_ZERO, KEY_P, KEY_LEFT_BRACKET, KEY_EQUAL, KEY_RIGHT_BRACKET, 0};

  float note;

  for (int i = 0; keys[i]; i++) {
    if (IsKeyPressed(keys[i])) {
      //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++) {
    if (IsKeyReleased(keys[i])) {
      synth->midi_note[i].noteOff = Pa_GetStreamTime(synth->stream);
      synth->midi_note[i].noteOffSample = synth->midi_note[i].elapsed;
      note = notes[i % 12][(synth->octave + (i / 12)) % 8];
    }
  }

  int mods[] = {KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, 0};
  synth->modi = 0;
  for (int i = 0; mods[i]; i++) {
    if (IsKeyDown(mods[i])) {
      synth->modifiers[synth->modi++] = mods[i];
    }      
  }
  
  if (IsKeyDown(265)) { // up
    for (int i = 0; i < synth->modi; i++) {
      if (synth->modifiers[i] == KEY_Z) {
        cc_step(&synth->cc_cutoff, 1);
      }
      if (synth->modifiers[i] == KEY_X) {
        cc_step(&synth->cc_resonance, 1);
      }
      if (synth->modifiers[i] == KEY_C) {
        cc_step(&synth->cc_pitch, 1);
      }
      if (synth->modifiers[i] == KEY_V) {
        cc_step(&synth->cc_lfo_freq, 1);
      }
      if (synth->modifiers[i] == KEY_B) {
        cc_step(&synth->cc_lfo_amp, 1);
      }
    }
  }
  if (IsKeyDown(264)) { // down
    for (int i = 0; i < synth->modi; i++) {
      if (synth->modifiers[i] == KEY_Z) {
        cc_step(&synth->cc_cutoff, -1);
      }
      if (synth->modifiers[i] == KEY_X) {
        cc_step(&synth->cc_resonance, -1);
      }
      if (synth->modifiers[i] == KEY_C) {
        cc_step(&synth->cc_pitch, -1);
      }
      if (synth->modifiers[i] == KEY_V) {
        cc_step(&synth->cc_lfo_freq, -1);
      }
      if (synth->modifiers[i] == KEY_B) {
        cc_step(&synth->cc_lfo_amp, -1);
      }
    }
  }
  if (IsKeyDown(KEY_ENTER)) { // down
    for (int i = 0; i < synth->modi; i++) {
      if (synth->modifiers[i] == KEY_Z) {
        cc_reset(&synth->cc_cutoff);
      }
      if (synth->modifiers[i] == KEY_X) {
        cc_reset(&synth->cc_resonance);
      }
      if (synth->modifiers[i] == KEY_C) {
        cc_reset(&synth->cc_pitch);
      }
      if (synth->modifiers[i] == KEY_V) {
        cc_reset(&synth->cc_lfo_freq);
      }
      if (synth->modifiers[i] == KEY_B) {
        cc_reset(&synth->cc_lfo_amp);
      }
    }
  }
}

void
draw_bars(synth_t * synth, int x, int y, int width, int height, int offset)
{
  char buf[64];
  int count = 0;
  
  snprintf(buf, sizeof buf, "%.3f", synth->adsr.a);
  synth->adsr.a = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "A: ", buf, synth->adsr.a , 0.0f, 2.0f);
  snprintf(buf, sizeof buf, "%.3f", synth->adsr.peak);
  synth->adsr.peak = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "P: ", buf, synth->adsr.peak , 0.0f, 1.0f);
  snprintf(buf, sizeof buf, "%.3f", synth->adsr.d);
  synth->adsr.d = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "D: ", buf, synth->adsr.d , 0.001f, 2.0f);
  snprintf(buf, sizeof buf, "%.3f", synth->adsr.s);
  synth->adsr.s = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "S: ", buf, synth->adsr.s , 0.0f, 1.0f);
  snprintf(buf, sizeof buf, "%.3f", synth->adsr.r);
  synth->adsr.r = GuiSlider((Rectangle){ x, y + count++ * (height + offset), width, height }, "R: ", buf, synth->adsr.r , -0.001f, 3.0f);
  snprintf(buf, sizeof buf, "%.3f", synth->cutoff);
  synth->cutoff = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "fC: ", buf, synth->cutoff , 0.0f, 11000.0f);
  /* snprintf(buf, sizeof buf, "%.3f", synth->resonance); */
  /* synth->resonance = GuiSliderBar((Rectangle){ x, y + count++ * (height + offset), width, height }, "fR: ", buf, synth->resonance , 0.001f, 5.0f); */
  snprintf(buf, sizeof buf, "%.3f", synth->lfo.freq);
  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
draw_signals(synth_t * synth, int x, int y, int width, int height)
{
  DrawRectangleLines(x, y, width, height, BLACK);

  int point_radius = 1.5;

  GuiSpinner((Rectangle){ x+ 100, y - 24 - 6, 100, 24 }, "rate divider: ", &(synth->viz.sample_rate_divider), 1, 10, 0);

  for (int i = x; i < WIDTH - x; i++) {
    DrawCircle(i , y + height / 2 + floor(250 *  synth->viz.wave[i - x]), point_radius, MAGENTA);
  }

/*   float adsr_duration = synth->adsr.a + synth->adsr.d + (synth->adsr.a + synth->adsr.d + synth->adsr.r) / 3.0 + synth->adsr.r; */
/*   for (int i = x; i < WIDTH - x; i++) { */
/*     for (int j = 0; j < MIDI_NOTES; j++) { */
/*       if (!synth->midi_note[j].active) */
/*         continue; */

/*       DrawCircle(i , y + height - 1 + 4.5*floor((WIDTH / 24) * - fix_adsr(&synth->adsr,  synth->midi_note[j].noteOn, synth->midi_note[j].noteOff, (i - x) * (adsr_duration * SAMPLE_RATE) / WIDTH, synth->midi_note[j].noteOffSample)), point_radius, BLUE); */
/*     } */
/*   } */
  for (int i = x; i < WIDTH - x; i++) {
    for (int j = 0; j < MIDI_NOTES; j++) {
      if (!synth->midi_note[j].active)
        continue;

      DrawCircle(i , y + height - 1 + 4.5*floor((WIDTH / 24) * - fix_adsr(&synth->adsr, synth->midi_note[j].noteOn, synth->midi_note[j].noteOff, synth->midi_note[j].elapsed, synth->midi_note[j].noteOffSample)), point_radius, GREEN);
    }
  }
}

#include "raystyle.h"
void
rayrun(void *synthData){
  synth_t * synth = (synth_t *)synthData;
  PaTime current_time = 0;
  PaTime prev_time = 0;

  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)) {
      synth->multi = !synth->multi;
    }

    // Draw
    //----------------------------------------------------------------------------------
    BeginDrawing();
    ClearBackground(BLACK);

    // GUI
    char buf[64];

    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, "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 + 42, 216, 6 }, "")) {
      synth->x = 1;
    }
    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 , 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);
    GuiSpinner((Rectangle){ WIDTH - 100 - 50 , 50 + 24 + 6, 100, 24 }, buf, &(synth->geni), 0, 6, 0);

    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 .. ]", 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();
    //----------------------------------------------------------------------------------

    current_time = Pa_GetStreamTime(synth->stream);
    //printf("%f :: %ld\n", current_time - prev_time, phase);

    prev_time = current_time;
  }
  CloseWindow();
}