#include #include #include #include #include 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 (); }