223 lines
5.2 KiB
C
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();
|
|
}
|