convotest/main.c
2024-06-15 16:56:16 -05:00

223 lines
5.2 KiB
C

#include<assert.h>
#include<inttypes.h>
#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<time.h>
#include<SDL2/SDL.h>
#include<SDL2/SDL_ttf.h>
#include<SDL2/SDL_image.h>
#include"sy.h"
#include"wav.h"
#include"button.h"
#include"tools.h"
#define max(x,y) (((x)>(y))?(x):(y))
#define min(x,y) (((x)<(y))?(x):(y))
#define WIDTH 320
#define HEIGHT 240
enum{BLP,BNS,BTR,BSQ,BSN};
int main(void)
{
SDL_Event event;
SDL_Renderer*ren=NULL;
SDL_Window*win=NULL;
TTF_Font*font=NULL;
Button buttons[16];
bool running=true;
const size_t samplerate=44100;
const size_t waveform_size=1024;
float waveform[waveform_size];
size_t filt_cutoff=500;
size_t nbuttons=0;
size_t osc_freq=440;
// Init SDL2
if(SDL_Init(SDL_INIT_EVERYTHING)<0)
{
fprintf(stderr,"error: failed to initialize SDL2\n");
goto quit;
}
// Init TTF
TTF_Init();
font=TTF_OpenFont("DejaVuSerif.ttf",12);
if(!font)
{
fprintf(stderr,"error: failed initialize SDL2 TTF\n");
goto quit;
}
// Create window
win=SDL_CreateWindow("ok",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WIDTH,HEIGHT,0);
if(!win)
{
fprintf(stderr,"error: failed to create window\n");
goto quit;
}
// Create renderer
ren=SDL_CreateRenderer(win,-1,0);
if(!ren)
{
fprintf(stderr,"error: failed to create renderer\n");
goto quit;
}
// Clear window
SDL_SetRenderDrawColor(ren,0,0,0,0);
SDL_RenderClear(ren);
SDL_RenderPresent(ren);
// Create buttons
#define create_button(n,_label) do{buttons[n]=(Button){.label=(_label),.x=nbuttons*25+5,.y=HEIGHT-20,.w=20,.h=16};++nbuttons;}while(0)
create_button(BLP,"LP");
create_button(BNS,"Ns");
create_button(BTR,"Tr");
create_button(BSQ,"Sq");
create_button(BSN,"Sn");
#undef create_button
// Initialize data
srand(time(NULL));
nois(waveform,waveform_size);
// Main loop
while(running)
{
if(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
running=false;
break;
// Mouse input
case SDL_MOUSEBUTTONDOWN:
switch(event.button.button)
{
case SDL_BUTTON_LEFT:
// Check each button
for(size_t i=0;i<nbuttons;++i)
if(event.button.x>(int)buttons[i].x&&
event.button.x<(int)buttons[i].x+(int)buttons[i].w&&
event.button.y>(int)buttons[i].y&&
event.button.y<(int)buttons[i].y+(int)buttons[i].h)
{
switch(i)
{
case BLP:
float windowsize=(((float)samplerate)/filt_cutoff);
/* printf("%luHz: %g\n",filt_cutoff,windowsize); */
/* printf("%luHz(44.1kHz): %g\n",filt_cutoff,((float)44100)/filt_cutoff); */
avgwindow(waveform,waveform_size,windowsize);
break;
case BNS:nois(waveform,waveform_size);break;
case BTR:tri(waveform,waveform_size,osc_freq);break;
case BSQ:sq(waveform,waveform_size,osc_freq);break;
case BSN:sn(waveform,waveform_size,osc_freq);break;
}
/* printf("'%s' pressed\n",buttons[i].label); */
break; // Do not click more than one button
}
break;
}
break;
// Keyboard input
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
// UI
case SDLK_ESCAPE:
case SDLK_q:
running=false;
break;
// Oscillators
case SDLK_n:nois(waveform,waveform_size);break;
case SDLK_t:tri(waveform,waveform_size,osc_freq);break;
case SDLK_e:sq(waveform,waveform_size,osc_freq);break;
case SDLK_i:sn(waveform,waveform_size,osc_freq);break;
// Filters, envelopes, etc.
case SDLK_s:sort(waveform,waveform_size);break;
case SDLK_r:shuf(waveform,waveform_size);break;
case SDLK_y:atk(waveform,waveform_size,5);break;
case SDLK_u:rel(waveform,waveform_size,10);break;
case SDLK_o:rotl(waveform,waveform_size);break;
case SDLK_a:
{
float windowsize=(((float)samplerate)/filt_cutoff);
/* printf("%luHz: %g\n",filt_cutoff,windowsize); */
/* printf("%luHz(44.1kHz): %g\n",filt_cutoff,((float)44100)/filt_cutoff); */
avgwindow(waveform,waveform_size,windowsize);
}
break;
// Parameters
case SDLK_UP:osc_freq+=(1/12.0)*osc_freq;break;
case SDLK_DOWN:osc_freq-=(1/12.0)*osc_freq;if(osc_freq<1)osc_freq=1;break;
case SDLK_EQUALS:filt_cutoff+=(1/12.0)*filt_cutoff;break;
case SDLK_MINUS:filt_cutoff-=(1/12.0)*filt_cutoff;if(filt_cutoff<1)filt_cutoff=1;break;
}
break;
default:
break;
}
}
// Render
SDL_SetRenderDrawColor(ren,0,0,0,255);
SDL_RenderClear(ren);
SDL_SetRenderDrawColor(ren,255,0,0,255);
for(size_t i=0;i<WIDTH;++i)
SDL_RenderDrawLine(ren,i,HEIGHT/2,i,max(HEIGHT/2-waveform[i*(waveform_size/WIDTH)]*100,0));
for(size_t i=0;i<nbuttons;++i)
button_draw(ren,font,&buttons[i]);
ttfprintf(ren,font,0xffffff,5,5,
"sr:%lu ns:%lu f:%lu co:%lu",
samplerate,
waveform_size,
osc_freq,
filt_cutoff
);
SDL_RenderPresent(ren);
SDL_Delay(20);
//usleep(20000);
}
// Clean up, exit
quit:
if(win)
SDL_DestroyWindow(win);
if(ren)
SDL_DestroyRenderer(ren);
if(font)
TTF_CloseFont(font);
SDL_Quit();
TTF_Quit();
}