stew

a monorepo of some sort
git clone git://git.nsmpr.xyz/stew.git
Log | Files | Refs

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 }