diff --git a/README.md b/README.md index 9b2c40a..29a2fc6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ .asoundrc (Должно быть в ~/) Нужно поменять rockchipes8316c, на вашу карту (aplay -L) -cc spark.c -lm -s -o spark modprobe snd-aloop + +cc spark_ncurses.c -lm -lncurses -s -ospark chmod +x audio_vis.sh ./audio_vis.sh diff --git a/audio_vis.sh b/audio_vis.sh index e1c7c7e..4eb9724 100755 --- a/audio_vis.sh +++ b/audio_vis.sh @@ -1,4 +1,2 @@ #!/bin/sh -cols=180 - -arecord --rate 48000 --buffer-size=2048 -D loopout -N -q -c 1 -f S24_LE -t raw | hexdump -e '/4 " %d"' | tr -d '*' | tr -d '-' | xargs -n $cols ./spark +arecord --rate 16000 --buffer-size=1024 -D loopout -MNqc 1 -f S24_LE -t raw | hexdump -e '/4 " %d"' | tr -d '*' | ./spark diff --git a/spark.c b/spark.c deleted file mode 100644 index a2d3307..0000000 --- a/spark.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include -#include -#include - -double min = 90000; -double max = 3000000; - -int parse_double(const char *str, double *res) { - char *ptr; - - *res = strtod(str, &ptr); - if (*ptr) - return 0; - - return 1; -} - -void print(double diff, double val) { - int lvl = (int)round((val - min + 1) / diff * 7); - if (lvl < 0) - lvl = 0; - - else if (lvl > 7) - lvl = 7; - - putchar('\xe2'); - putchar('\x96'); - putchar('\x81' + lvl); -} - -int main(int argc, char **argv) { - argv++; - argc--; - - if (argc == 0) { - fprintf(stderr, "spark: missing operands\n"); - return 1; - } - - size_t as = argc / 2; - double *a = malloc((as + 1) * sizeof(double)); - if (a == NULL) - return 1; - - size_t j = 0; - for (size_t i = 0; i < as; i++) { - double val = 0; - if (!parse_double(argv[j], &val)) { - j++; - continue; - } - - double val2 = 0; - if (!parse_double(argv[j + 1], &val)) { - j++; - continue; - } - - a[i] = (val + val2) / 2; - j++; - } - - double diff = max - min + 1; - if (diff < 1) - diff = 1; - - for (size_t i = 0; i < as; i++) - print(diff, a[i]); - - putchar('\r'); - - free(a); - return 0; -} diff --git a/spark_ncurses.c b/spark_ncurses.c new file mode 100644 index 0000000..16d1539 --- /dev/null +++ b/spark_ncurses.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(); + } +}