#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, aflag = 0, *bitshuffle, usage(); register int i, ind; float mixIndex = .5, *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|m|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 'm': mixIndex = atof(arg_option); break; case 'f': strcpy(file, arg_option); 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) ); } makehanning( Hwin, Wanal, Wsyn, Nw, N, I, 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 */ for ( i=0; i < N; i += 2 ) { int index = 0; float min = 1e32, max = -1e32, target, delta = 1e32; for ( ind=0; ind < files; ind++ ) { float current; current = *(*(chans+ind)+i); if (current > max ) max = current; if (current < min) min = current; } /* use base 10 logarithm of minimum and maximum */ if ( min <= 0.0 ) min = -10.; else min = log10( min ); if ( max <= 0.0 ) max = -10.; else max = log10( max ); /* find target magnitude */ target = min + ((max - min) * mixIndex); for ( ind=0; ind < files; ind++ ) { float diff, current = log10( *(*(chans+ind)+i) ); diff = fabs(target-current); if ( diff < delta ) { delta = diff; index = ind; } } *((*chans)+i) = *(*(chans+index)+i); *((*chans)+i+1) = *(*(chans+index)+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, "lcd: multiple file spectral compositing\n" "%% lcd [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" " m: mix index between input files [0-1] (.5)\n" " h: this wise guide\n"); exit(woof); }