stew

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

fade.c (2162B)


      1 #include <u.h>
      2 #include <libc.h>
      3 
      4 #include "util.h"
      5 
      6 #define DefLength 8957
      7 /*
      8  * Given 44100 samplerate, this DefLength should result
      9  * in roughly 0.2 ms long output, which should be around
     10  * the point where changes in timbre start to be perceptable
     11  * by human ear.
     12  *
     13  * Probably.
     14  *
     15  * It is also a whole number multiple of draw's DefLength,
     16  * which should give us product that loops nicely.
     17  */
     18 
     19 
     20 Aud *files, output, envelope;
     21 int fcount;
     22 
     23 void load(Aud *aud, char *path);
     24 double env(double);
     25 double slope(double);
     26 double slope(double);
     27 void apply(Aud *, Aud *, double);
     28 
     29 void
     30 usage(void)
     31 {
     32 	fprint(2, "usage: %s [-e file] [-n count] wavefile1 wavefile2 ...\n", argv0);
     33 	exits("usage");
     34 }
     35 
     36 void
     37 main(int argc, char **argv)
     38 {
     39 	output.n = DefLength;
     40 
     41 	ARGBEGIN {
     42 	case 'n':
     43 		output.n = strtol(EARGF(usage()), nil, 0);
     44 		break;
     45 	default:
     46 		usage();
     47 	} ARGEND
     48 	if (argc < 2) usage();
     49 
     50 	fcount = argc;
     51 	files = malloc(sizeof(Aud) * fcount);
     52 
     53 	int i;
     54 	for (i = 0; i < fcount; i++) {
     55 		load(files + i, argv[i]);
     56 		apply(&output, &files[i], - (double)i);
     57 	}
     58 	write(1, output.p, output.n * 4);
     59 }
     60 
     61 void
     62 load(Aud *aud, char *path)
     63 {
     64 	int fd;
     65 	if ((fd = open(path, OREAD)) < 0) sysfatal("load: %r");
     66 	if ((aud->n = read(fd, aud->p, sizeof(aud->p))) < 0) sysfatal("load: %r");
     67 	aud->n = aud->n / 4;
     68 	close(fd);
     69 }
     70 
     71 void
     72 apply(Aud *dst, Aud *src, double dx)
     73 {
     74 	int i, j;
     75 	Frame *fs, *fd;
     76 	for (i = 0; i < output.n; i++) {
     77 
     78 		double p = ((double)fcount - 1) * (double)i / (double)output.n;
     79 		double v = slope(p + dx);
     80 
     81 		j = i % src->n;
     82 
     83 		fd = (Frame *)&dst->p[i];
     84 		fs = (Frame *)&src->p[j];
     85 		fd->c[0] += fs->c[0] * v;
     86 		fd->c[1] += fs->c[1] * v;
     87 	}
     88 }
     89 
     90 double
     91 slope(double x)
     92 {
     93 	/* TODO: maybe I should use sine-shaped slope instead of triangle one */
     94 	if (x < 0) x = -x;
     95 	if (x > 1) x = 1;
     96 	return 1 - x;
     97 }
     98 
     99 double
    100 env(double I)
    101 {
    102 	return I;
    103 
    104 	/*int i;
    105 	double delta, a ,b;
    106 	i = (int)(I * tolen(envelope.n)) & (-2);
    107 	delta = (I * tolen(envelope.n)) - (double)i;
    108 	a = (double)(envelope.p[i] + envelope.p[i + 1]) / 4.0 / (double)0x7fff + 0.5;
    109 	b = (double)(envelope.p[i + 2] + envelope.p[i + 3]) / 4.0 / (double)0x7fff + 0.5;
    110 	return a * delta + b * (1 - delta);*/
    111 }