FreeCalypso > hg > freecalypso-tools
view loadtools/buzplaypwt.c @ 891:8e5f68b6420a
doc/Host-tools-overview: document fc-imyplay
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 03 Apr 2022 05:33:23 +0000 |
parents | 502aec4c1e8e |
children | 85091e14be9c |
line wrap: on
line source
/* * fc-buzplay: in this module we are going to implement parsing, * uploading and play of PWT melodies. */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <stdlib.h> static struct pwt_note { char *name; int code; } pwt_notes_table[] = { {"f4", 47}, /* 349 Hz */ {"fs4", 43}, /* 370 Hz */ {"g4", 39}, /* 392 Hz */ {"gs4", 35}, /* 415 Hz */ {"a4", 31}, /* 440 Hz */ {"as4", 27}, /* 466 Hz */ {"b4", 23}, /* 494 Hz */ {"c5", 19}, /* 523 Hz */ {"cs5", 15}, /* 554 Hz */ {"d5", 11}, /* 587 Hz */ {"ds5", 7}, /* 622 Hz */ {"e5", 3}, /* 659 Hz */ {"f5", 46}, /* 698 Hz */ {"fs5", 42}, /* 740 Hz */ {"g5", 38}, /* 784 Hz */ {"gs5", 34}, /* 831 Hz */ {"a5", 30}, /* 880 Hz */ {"as5", 26}, /* 932 Hz */ {"b5", 22}, /* 988 Hz */ {"c6", 18}, /* 1047 Hz */ {"cs6", 14}, /* 1109 Hz */ {"d6", 10}, /* 1175 Hz */ {"ds6", 6}, /* 1245 Hz */ {"e6", 2}, /* 1319 Hz */ {"f6", 45}, /* 1397 Hz */ {"fs6", 41}, /* 1480 Hz */ {"g6", 37}, /* 1568 Hz */ {"gs6", 33}, /* 1661 Hz */ {"a6", 29}, /* 1760 Hz */ {"as6", 25}, /* 1865 Hz */ {"b6", 21}, /* 1976 Hz */ {"c7", 17}, /* 2093 Hz */ {"cs7", 13}, /* 2217 Hz */ {"d7", 9}, /* 2349 Hz */ {"ds7", 5}, /* 2489 Hz */ {"e7", 1}, /* 2637 Hz */ {"f7", 44}, /* 2794 Hz */ {"fs7", 40}, /* 2960 Hz */ {"g7", 36}, /* 3136 Hz */ {"gs7", 32}, /* 3322 Hz */ {"a7", 28}, /* 3520 Hz */ {"as7", 24}, /* 3729 Hz */ {"b7", 20}, /* 3951 Hz */ {"c8", 16}, /* 4186 Hz */ {"cs8", 12}, /* 4435 Hz */ {"d8", 8}, /* 4699 Hz */ {"ds8", 4}, /* 4978 Hz */ {"e8", 0}, /* 5274 Hz */ /* table search terminator */ {0, -1} }; cmd_playt(argc, argv) char **argv; { FILE *f; char linebuf[256], *cp, *fields[3]; int lineno, nfields; char *targv[5], argbuf1[16], argbuf2[16], argbuf3[16]; struct pwt_note *tp; u_long global_vol, note_vol, duration, total_ms; int rc, timeout; f = fopen(argv[1], "r"); if (!f) { perror(argv[1]); return(-1); } if (argv[2]) { global_vol = strtoul(argv[2], 0, 0); if (global_vol < 1 || global_vol > 64) { fprintf(stderr, "error: invalid global volume argument\n"); fclose(f); return(-1); } } else global_vol = 64; printf("Uploading the melody to the target\n"); targv[0] = "IT"; targv[1] = 0; tpinterf_make_cmd(targv); if (tpinterf_send_cmd() < 0) { fclose(f); return(-1); } rc = tpinterf_pass_output(1); if (rc) { fclose(f); return(rc); } total_ms = 0; for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) { cp = index(linebuf, '\n'); if (!cp) { fprintf(stderr, "%s line %d: missing newline\n", argv[1], lineno); fclose(f); return(-1); } cp = linebuf; nfields = 0; for (;;) { while (isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') break; if (nfields >= 3) { fprintf(stderr, "%s line %d: too many fields\n", argv[1], lineno); fclose(f); return(-1); } fields[nfields++] = cp; while (*cp && !isspace(*cp)) cp++; if (*cp) *cp++ = '\0'; } if (!nfields) continue; if (nfields == 3) { for (tp = pwt_notes_table; tp->name; tp++) if (!strcmp(tp->name, fields[0])) break; if (tp->code < 0) { fprintf(stderr, "%s line %d: invalid note name\n", argv[1], lineno); fclose(f); return(-1); } note_vol = strtoul(fields[1], 0, 0); if (note_vol < 1 || note_vol > 64) { fprintf(stderr, "%s line %d: invalid note volume\n", argv[1], lineno); fclose(f); return(-1); } duration = strtoul(fields[2], 0, 0); if (duration < 1 || duration > 0xFFFF) { fprintf(stderr, "%s line %d: the duration number is out of range\n", argv[1], lineno); fclose(f); return(-1); } sprintf(argbuf1, "%u", (unsigned) tp->code); sprintf(argbuf2, "%u", ((global_vol * note_vol + 63) >> 6) - 1); sprintf(argbuf3, "%u", duration); targv[0] = "ET"; targv[1] = argbuf1; targv[2] = argbuf2; targv[3] = argbuf3; targv[4] = 0; } else if (nfields == 2 && !strcmp(fields[0], "rest")) { duration = strtoul(fields[1], 0, 0); if (duration < 1 || duration > 0xFFFF) { fprintf(stderr, "%s line %d: the duration number is out of range\n", argv[1], lineno); fclose(f); return(-1); } sprintf(argbuf1, "%u", duration); targv[0] = "EP"; targv[1] = argbuf1; targv[2] = 0; } else { fprintf(stderr, "%s line %d: invalid syntax\n", argv[1], lineno); fclose(f); return(-1); } /* send it to the target */ tpinterf_make_cmd(targv); if (tpinterf_send_cmd() < 0) { fclose(f); return(-1); } rc = tpinterf_pass_output(1); if (rc) { fclose(f); return(rc); } /* account for the duration */ total_ms += duration * 5; } fclose(f); if (!total_ms) { fprintf(stderr, "%s is empty!\n", argv[1]); return(-1); } printf("Requesting play of the uploaded melody on the target\n"); targv[0] = "P"; targv[1] = 0; tpinterf_make_cmd(targv); if (tpinterf_send_cmd() < 0) return(-1); timeout = total_ms / 1000 + 2; return tpinterf_pass_output(timeout); }