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 }