#include #include #include #include #include #include #define Max_Files 64 #define Max_Path_Len 1024 int main(argc, argv) int argc; char **argv; { int R = 44100, N = 1024, N2, Nw = 0, Nw2, D = 0, I = 0, files, in, on, grab, eof = 0, invert = 0, aflag = 0, *bitshuffle, usage(); register int i, ind; float keep, *Hwin, *Wanal, *Wsyn, **inputs, **buffers, **chans, *output, *trigland; char ch, file[1024], **filelist; FILE **fp; MrSoundStruct *soundStructs; if (argc < 3) usage(1); synt = 0.0; while( (ch = crack( argc, argv, "R|N|M|D|I|f|ih", 0 )) != 0 ) { switch(ch) { case 'R': R = atoi(arg_option); break; case 'N': N = atoi(arg_option); break; case 'M': Nw = atoi(arg_option); break; case 'D': D = atoi(arg_option); break; case 'I': I = atoi(arg_option); break; case 'f': strcpy(file, arg_option); break; case 'i': invert = 1; break; case 'h': usage(1); } } if (Nw == 0) Nw = N; if (D == 0) D = Nw / 2; if (aflag) I = 0; else if (I == 0) I = D; myPI = 4. * atan(1.); myTWOPI = 8. * atan(1.); N2 = N>>1; Nw2 = Nw>>1; filelist = (char **) space( Max_Files, sizeof(char *) ); fp = (FILE **) space( Max_Files, sizeof(FILE *) ); for ( i=0; i < Max_Files; i++ ) *(filelist+i) = (char *) space( Max_Path_Len, sizeof(char) ); if (( *fp = fopen( file, "r" ) ) == NULL) { fprintf(stderr,"What is %s?\n", file); exit(-1); } i = 0; while ( (grab = fscanf( *fp, "%s\n", *(filelist+i) )) != EOF && i < Max_Files ) { if ( grab != 0 ) ++i; } files = i; fclose(*fp); /* allocate space for sound file structures */ soundStructs = (MrSoundStruct *) space( files, sizeof(MrSoundStruct) ); /* open sound files for reading */ for ( i=0; i < files; i++ ) { if ( ( *(fp+i) = GetMrSoundStream( *(filelist+i), soundStructs+i )) == NULL ) { fprintf(stderr,"astral cannot open %s\n",*(filelist+i)); exit(-1); } if ( (soundStructs+i)->dataFormat != SND_FORMAT_FLOAT ) { fprintf(stderr,"%s is not a 32-bit floating point sound file\n", *(filelist+i)); exit(-1); } } /* edit allocation calls */ Wanal = (float *) space( Nw, sizeof(float) ); Wsyn = (float *) space( Nw, sizeof(float) ); Hwin = (float *) space( Nw, sizeof(float) ); output = (float *) space( Nw, sizeof(float) ); inputs = (float **) space( files, sizeof(float *) ); buffers = (float **) space( files, sizeof(float *) ); chans = (float **) space( files, sizeof(float *) ); for ( i=0; i < files; i++ ) { *(inputs+i) = (float *) space( Nw, sizeof(float) ); *(buffers+i) = (float *) space( N, sizeof(float) ); *(chans+i) = (float *) space( N+2, sizeof(float) ); } if ( (Nw / D) == 2 ) makehanning( Hwin, Wanal, Wsyn, Nw, N, I, 0, 1 ); else makehanning( Hwin, Wanal, Wsyn, Nw, N, I, 0, 0 ); /* FFT cosine funk */ trigland = (float *) space( N2, sizeof(float) ); /* FFT bit shuffle */ bitshuffle = (int *) space( 3 + (int) sqrt( (float) N2 ), sizeof(int) ); init_rdft( N, bitshuffle, trigland ); in = -Nw; if ( D ) on = (in*I)/D; else on = in; grab = 0; eof = 0; while ( !eof ) { in += D; on += I; /* develop a more sophisticated eof mechanism */ for ( ind=0; ind < files; ind++ ) { if (eof) (void) floatin( *(inputs+ind), Nw, D, *(fp+ind) ); else grab = floatin( *(inputs+ind), Nw, D, *(fp+ind) ); fold( *(inputs+ind), Wanal, Nw, *(buffers+ind), N, in ); rdft( N, 1, *(buffers+ind), bitshuffle, trigland ); leanconvert( *(buffers+ind), *(chans+ind), N2 ); } /* process spectra */ if (invert) { for ( i=0; i < N; i+=2 ) { int currentIndex = 0; keep = *((*chans)+i); for ( ind=1; ind < files; ind++ ) { if ( *(*(chans+ind)+i) < keep ) { keep = *(*(chans+ind)+i); currentIndex = ind; } } *((*chans)+i) = *(*(chans+currentIndex)+i); *((*chans)+i+1) = *(*(chans+currentIndex)+i+1); } } else { for ( i=0; i < N; i+=2 ) { int currentIndex = 0; keep = *((*chans)+i); for ( ind=1; ind < files; ind++ ) { if ( *(*(chans+ind)+i) > keep ) { keep = *(*(chans+ind)+i); currentIndex = ind; } } *((*chans)+i) = *(*(chans+currentIndex)+i); *((*chans)+i+1) = *(*(chans+currentIndex)+i+1); } } if ( I == 0 ) { fwrite( *chans, sizeof(float), N+2, stdout ); fflush( stdout ); continue; } leanunconvert( *chans, *buffers, N2 ); rdft( N, -1, *buffers, bitshuffle, trigland ); overlapadd( *buffers, N, Wsyn, output, Nw, on ); shiftout( output, Nw, I, on ); /* fix eof treatment */ eof = grab; } exit(0); } int usage(woof) int woof; { fprintf(stderr, "astral: multiple file spectral compositing\n" "%% astral [flags] > floatsams\n" " N: fft length [2^n] (1024)\n" " R: sampling rate (44100)\n" " M: window size in samples (N)\n" " D: decimation factor in samples (M/2)\n" " I: interpolation factor in samples (D)\n" " f: soundfile list\n" " i: invert evaluation\n" " h: this wise guide\n"); exit(woof); }