alsa-visual/spark_ncurses.c

133 lines
1.9 KiB
C

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <ncurses.h>
#include <sys/ioctl.h>
#include <ctype.h>
#include <math.h>
#define NARGS 4096
#define ARG_SIZE 50
#define MAX 1000000
#define MIN 50000
int args;
double values[NARGS + 1];
struct winsize ws;
int parse_double(const char *str, double *res) {
char *ptr;
*res = strtod(str, &ptr);
if (*ptr)
return 0;
return 1;
}
int add_value(const char *str) {
if (args >= sizeof(values) / sizeof(double) || args > ws.ws_col)
return 1;
double val = 0;
if (!parse_double(str, &val))
return 1;
values[args] = val;
args++;
return 0;
}
void stdin_read(void) {
char arg[ARG_SIZE + 1];
char *p = arg;
fflush(stdin);
while (1) {
int c = getchar();
if (c == EOF)
return;
else if (c == ' ' && p != arg) {
*p = '\0';
p = arg;
if (add_value(arg))
break;
}
else {
*p = c;
if (p + 1 == arg + sizeof(arg))
break;
p++;
}
}
}
void mvprint(int y, int x, int lvl) {
char *fmt = "@";
if (lvl < 4) {
fmt = "/";
if (y > ws.ws_row / 2)
fmt = "\\";
}
else if (lvl - 4 <= 2)
fmt = "+";
mvprintw(y, x, "%s", fmt);
}
void print(double value, double diff, int col) {
size_t m_screen = ws.ws_row / 2;
if (value >= 0) {
int lvl = (int)round((value - MIN + 1) / diff * 2);
mvprint(m_screen - lvl, col, lvl);
}
else {
int lvl = (int)round(((value * -1) - MIN + 1) / diff * 2);
mvprint(m_screen + lvl, col, lvl);
}
}
void sig_handler(int sig) {
(void)sig;
endwin();
exit(0);
}
int main(void) {
signal(SIGINT, sig_handler);
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
return 1;
initscr();
curs_set(0);
timeout(0);
double diff = MAX - MIN + 1;
if (diff < 1)
diff = 1;
while (1) {
args = 0;
stdin_read();
clear();
for (int i = 1; i < args - 1; i++)
print((values[i - 1] + values[i] + values[i + 1]) / 4, diff, i);
refresh();
}
}