harm.c (1572B)
1 /* 2 Input is a list of floats. 3 Output is a PCM audio of sum of harmonics with corresponding amplitudes. 4 */ 5 6 #include <u.h> 7 #include <libc.h> 8 #include <bio.h> 9 10 #include "util.h" 11 12 long baselen = 0, outlen = 8363; // samplerate of FastTracker samples 13 double amp = 1; 14 15 void 16 usage(void) 17 { 18 fprint(2, "usage: %s [-a amplitude] [-b length] [-l length]\n", argv0); 19 exits("usage"); 20 } 21 22 void 23 main(int argc, char **argv) 24 { 25 ARGBEGIN{ 26 case 'a': 27 amp = strtod(EARGF(usage()), nil); 28 break; 29 case 'b': 30 baselen = strtol(EARGF(usage()), nil, 0); 31 if (baselen <= 0) { 32 fprint(2, "invalid baselen\n"); 33 exits("wrong args"); 34 } 35 break; 36 case 'l': 37 outlen = strtol(EARGF(usage()), nil, 0); 38 if (outlen <= 0) { 39 fprint(2, "invalid outlen\n"); 40 exits("wrong args"); 41 } 42 break; 43 default: 44 usage(); 45 } ARGEND 46 if (argc != 0) usage(); 47 48 if (baselen == 0) baselen = outlen; 49 50 double *buf = mallocz(sizeof(double) * outlen, 1); 51 Biobuf *bp = Bfdopen(0, OREAD); 52 char *s; 53 double h = 1; 54 int i; 55 while((s = Brdstr(bp, '\n', 1)) != nil) { 56 double d = strtod(s, nil); 57 for (i = 0; i < outlen; i++) { 58 buf[i] += sin(2.0 * PI * ((double)i / (double)baselen) * h) * d; 59 } 60 h = h + 1.0; 61 if (h > baselen / 2) break; // no point to freqs bigger than what audio resolution would give us 62 } 63 64 u32int *out = malloc(sizeof(u32int) * outlen); 65 66 for (i = 0; i < outlen; i++) { 67 double d = buf[i] * amp; 68 if (d > 1.0) d = 1; 69 if (d < -1.0) d = -1; 70 Frame *f; 71 f = (Frame *)(&out[i]); 72 f->c1 = d * 0x7fff; 73 f->c2 = f->c1; 74 } 75 76 write(1, out, outlen * sizeof(u32int)); 77 78 exits(0); 79 }