Skip to content

Instantly share code, notes, and snippets.

@xsbee
Created April 30, 2023 09:41
Show Gist options
  • Save xsbee/35b4d1e645f585eecfaf2d582eefa55f to your computer and use it in GitHub Desktop.
Save xsbee/35b4d1e645f585eecfaf2d582eefa55f to your computer and use it in GitHub Desktop.
Displays waveform of default input device using SDL
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <SDL.h>
struct draw_context
{
float window[1024];
SDL_FPoint points[1024];
SDL_AudioDeviceID dev;
};
static void capture_callback (void* userdata, unsigned char* samples, int num_bytes)
{
struct draw_context *c = userdata;
int N = num_bytes / sizeof(float);
int win_off = 1024 - N;
memmove (c->window, c->window + N, win_off * sizeof(float));
memcpy (c->window + win_off, samples, num_bytes);
}
static inline void draw (SDL_Renderer *r, struct draw_context *c)
{
SDL_FPoint point;
int i;
float x = 0;
SDL_SetRenderDrawColor(r, 0, 0, 0, 0xFF);
SDL_RenderClear (r);
SDL_LockAudioDevice (c->dev);
for (i = 0; i < 1024; ++i)
{
point.x = x;
point.y = (0.5 * c->window[i] + 0.5) * 720;
c->points[i] = point;
x += 1.25f;
}
SDL_UnlockAudioDevice (c->dev);
SDL_SetRenderDrawColor(r, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderDrawLinesF (r, c->points, 1024);
SDL_RenderPresent (r);
}
int main(int argc, char ** argv)
{
SDL_Init (SDL_INIT_AUDIO | SDL_INIT_VIDEO);
SDL_Window *win = NULL;
SDL_Renderer *r = NULL;
SDL_Event evt;
SDL_AudioDeviceID dev;
SDL_AudioSpec want, have;
struct draw_context *ctx;
ctx = calloc (sizeof (struct draw_context), 1);
if (!ctx)
{
fputs ("Failed allocating `struct draw_context'", stderr);
goto end;
}
int running = 1;
want.samples = 800;
want.freq = 48000;
want.format = AUDIO_F32;
want.channels = 1;
want.callback = capture_callback;
want.userdata = ctx;
dev = SDL_OpenAudioDevice (NULL, 1, &want, &have, 0);
if (!dev)
{
fprintf (stderr, "SDL_OpenAudioDevice(): %s\n", SDL_GetError ());
goto end;
}
win = SDL_CreateWindow (argv[0],
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1280, 720, 0);
if (!win)
{
fprintf (stderr, "SDL_CreateWindow(): %s\n", SDL_GetError ());
goto end;
}
r = SDL_CreateRenderer (win, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!r)
{
fprintf (stderr, "SDL_CreateRenderer(): %s\n", SDL_GetError());
goto end;
}
SDL_PauseAudioDevice (dev, 0);
while (running)
{
while (SDL_PollEvent (&evt))
switch (evt.type)
{
case SDL_QUIT:
running = 0;
break;
case SDL_KEYDOWN:
switch (evt.key.keysym.sym)
{
case SDLK_ESCAPE:
running = 0;
break;
default:
break;
}
break;
default:
break;
}
draw (r, ctx);
}
SDL_PauseAudioDevice (dev, 1);
end:
if (r)
SDL_DestroyRenderer (r);
if (win)
SDL_DestroyWindow (win);
if (dev)
SDL_CloseAudioDevice (dev);
if (ctx)
free (ctx);
SDL_Quit ();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment