6082
Ker-hazy.
#define CYCLES 6
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <string.h>
typedef float sample;
#define REALFILES 25
#define FILES REALFILES
// perl -e 'for (`ls IN`) {chomp; $a = "IN/$_"; s/(.+?)\.mp3$/OUT\/$1.wav/; `lame --decode -t $a $_`; }'
char *all[REALFILES] =
{"OUT/botb_0379.wav",
"OUT/botb_0411.wav",
"OUT/botb_0429.wav",
"OUT/botb_0442.wav",
"OUT/botb_0460.wav",
"OUT/botb_0386.wav",
"OUT/botb_0416.wav",
"OUT/botb_0431.wav",
"OUT/botb_0449.wav",
"OUT/botb_0463.wav",
"OUT/botb_0388.wav",
"OUT/botb_0417.wav",
"OUT/botb_0432.wav",
"OUT/botb_0450.wav",
"OUT/botb_0464.wav",
"OUT/botb_0389.wav",
"OUT/botb_0419.wav",
"OUT/botb_0433.wav",
"OUT/botb_0453.wav",
"OUT/botb_0465.wav",
"OUT/botb_0393.wav",
"OUT/botb_0428.wav",
"OUT/botb_0439.wav",
"OUT/botb_0459.wav",
"OUT/botb_0466.wav"
};
#define BASE (M_PI*2/44100*8.1757989156)
#define SEMITONE (pow(2,1.0/12.0))
sample *load(char *file, int &size) {
struct stat sb;
stat(file, &sb);
FILE *in = fopen(file, "r");
size = sb.st_size;
short *out = (short *)malloc(size);
fread(out, size/sizeof(short), sizeof(short), in);
fclose(in);
size /= sizeof(short);
int undersize = size;
//for (size = 1; size < undersize; size *= 2);
sample *vals = (sample *)malloc(size*sizeof(sample));
for(int c = 0; c < undersize; c++)
vals[c] = ((sample)out[c])/SHRT_MAX;
for(int c = undersize; c < size; c++)
vals[c] = 0;
free(out);
return vals;
}
#define UPH(z) ((z)/2 + (z)%2)
struct haar {
sample *sig;
sample *noi;
int len;
haar() : sig(0), noi(0), len(0) {}
};
const sample sqrt2 = sqrt(2);
void haarFromTo (haar &a, haar &b) {
b.len = UPH(a.len);
b.sig = (sample *)malloc(sizeof(sample)*b.len);
b.noi = (sample *)malloc(sizeof(sample)*b.len);
for(int c = 0; c < a.len; c+=2) {
b.sig[c/2] = (a.sig[c] + a.sig[c+1])/sqrt2;
b.noi[c/2] = (a.sig[c] - a.sig[c+1])/sqrt2;
}
printf("haar from %d to %d\n", a.len, b.len);
}
struct file { haar contents[2][CYCLES]; };
void allocFile(file &f, int qsongl) {
qsongl = UPH(qsongl);
for (int s = 0; s < 2; s++) {
f.contents[s][0].sig = (sample *)malloc(sizeof(sample)*qsongl);
f.contents[s][0].noi = (sample *)malloc(sizeof(sample)*qsongl);
f.contents[s][0].len = qsongl;
for(int c = 0; c < f.contents[s][0].len; c++) {
f.contents[s][0].sig[c] = 0;
f.contents[s][0].noi[c] = 0;
}
}
}
void fillFile(file &f, char *name) {
int qsongl;
sample *qsong = load(name, qsongl);
allocFile(f, qsongl);
// DESTEREO, DECOMPOSE:
for(int c = 0; c < qsongl; c++) {
f.contents[c%2][0].sig[c/2] = qsong[c];
}
free(qsong);
}
void decompose(file &f) {
for(int s = 0; s < 2; s++) {
for(int c = 0; c < CYCLES-1; c++) {
haarFromTo(f.contents[s][c], f.contents[s][c+1]);
}
}
}
void recompose(file &f) {
for(int s = 0; s < 2; s++) {
for(int c = CYCLES-2; c >= 0; c--) {
for(int d = 0; d < f.contents[s][c].len; d++) {
f.contents[s][c].sig[d] = (f.contents[s][c+1].sig[d/2]
+ f.contents[s][c+1].noi[d/2] * (d%2?-1:1))
/ sqrt2;
}
}
}
}
#define OUTS (44100 * 60)
int main() {
int outp = 0;
sample *out = (sample *)malloc(OUTS*sizeof(sample)*2);
short *sout = (short *)malloc(OUTS*sizeof(short)*2);
printf("...doomed...\n");
file in[FILES];
for(int c = 0; c < FILES; c++) {
printf("File %d of %d, %s:\n", c, FILES, all[c]);
fillFile(in[c], all[c]);
decompose(in[c]);
}
file final;
allocFile(final, OUTS);
decompose(final);
printf("DOOMED!\n");
// SET THE STAGE:
#define CIL(a, b) if (fabs(a) < fabs(b)) a = b
for(int z = 0; z < FILES; z++) {
for(int s = 0; s < 2; s++) {
for(int c = 1; c < CYCLES; c++) { // Go from the bottom up. Why? I dunno.
for(int d = 0; d < final.contents[s][c].len && d < in[z].contents[s][c].len; d++) {
CIL(final.contents[s][c].sig[d], in[z].contents[s][c].sig[d]);
CIL(final.contents[s][c].noi[d], in[z].contents[s][c].noi[d]);
}
}
}
}
printf("...done\n");
// HAAR:
recompose(final);
outp = 0;
// RESTEREO:
{ int c = 0;
for(int d = 0; d < final.contents[0][c].len; d++) {
for(int s = 0; s < 2; s++) {
out[outp++] = final.contents[s][c].sig[d];
}
}
}
// FLATTEN:
sample roof = 0;
for(int c = 0; c < outp; c++)
if (fabs(out[c]) > roof)
roof = fabs(out[c]);
printf("...%f\n", roof);
for(int c = 0; c < outp; c++)
sout[c] = (out[c]/roof)*SHRT_MAX;
// ------------------ SAVE ------------------
FILE *fout = fopen("haar.out", "w");
fwrite(sout, outp, sizeof(short), fout);
#endif
return 0;
}