This is main.c in view mode; [Download] [Up]
#include "pv.h" #include <dsp/arrayproc.h> complex zero = { 0., 0. } ; complex one = { 1., 0. } ; float PI ; float TWOPI ; float synt ; main( int argc, char *argv[] ) { int R, N, N2, Nw, Nw2, D, I, i, in, on, eof = 0, obank = 0, Np ; float P, *Hwin, *Wanal, *Wsyn, *input, *winput, *lpcoef, *buffer, *channel, *output ; void vvmult( float *out, float *a, float *b, int n ) ; float maxof( float *a, int n ) ; if ( argc < 9 ) { fprintf( stderr, "%s%s%s%s%s%s%s%s%s", "USAGE: pvdsp R N Nw D I P Np synt < shortsams > shortsams\n", " R - sampling rate in Hz\n", " N - FFT length in samples (must be 2^n <= 1024)\n", " Nw - window size in samples\n", " D - decimation factor in samples [0 for synthesis only]\n", " I - interpolation factor in samples [0 for analysis only]\n", " P - oscillator bank pitch factor [0 for overlap-add resynthesis]\n", " Np - linear prediction order [0 for none]\n", " synt - synthesis channel threshold [0 for all channels]\n" ) ; exit( 0 ) ; } /* * pick up arguments from command line */ R = atoi( argv[1] ) ; /* sampling rate */ N = atoi( argv[2] ) ; /* FFT length */ Nw = atoi( argv[3] ) ; /* window size */ D = atoi( argv[4] ) ; /* decimation factor */ I = atoi( argv[5] ) ; /* interpolation factor */ P = atof( argv[6] ) ; /* oscillator bank pitch factor */ Np = atoi( argv[7] ) ; /* linear prediction order */ synt = atof( argv[8] ) ; /* synthesis threshhold */ freopen( "pv.out", "w", stderr ) ; fprintf( stderr, "pv parameters:\n" ) ; fprintf( stderr, "R = %d\n", R ) ; fprintf( stderr, "N = %d\n", N ) ; fprintf( stderr, "Nw = %d\n", Nw ) ; fprintf( stderr, "D = %d\n", D ) ; fprintf( stderr, "I = %d\n", I ) ; fprintf( stderr, "P = %g\n", P ) ; fprintf( stderr, "Np = %d\n", Np ) ; fprintf( stderr, "synt = %g\n", synt ) ; fflush( stderr ) ; PI = 4.*atan(1.) ; TWOPI = 8.*atan(1.) ; obank = P != 0. ; N2 = N>>1 ; Nw2 = Nw>>1 ; /* * allocate memory */ fvec( Wanal, Nw ) ; /* analysis window */ fvec( Wsyn, Nw ) ; /* synthesis window */ fvec( input, Nw ) ; /* input buffer */ fvec( Hwin, Nw ) ; /* plain Hamming window */ fvec( winput, Nw ) ; /* windowed input buffer */ fvec( lpcoef, Np+1 ) ; /* lp coefficients */ fvec( buffer, N ) ; /* FFT buffer */ fvec( channel, N+2 ) ; /* analysis channels */ fvec( output, Nw ) ; /* output buffer */ /* * create windows */ makewindows( Hwin, Wanal, Wsyn, Nw, N, I, obank ) ; /* * initialize input and output time values (in samples) */ in = -Nw ; if ( D ) on = (in*I)/D ; else on = in ; /* * main loop--perform phase vocoder analysis-resynthesis */ while ( !eof ) { /* * increment times */ in += D ; on += I ; /* * analysis: input D samples; window, fold and rotate input * samples into FFT buffer; take FFT; and convert to * amplitude-frequency (phase vocoder) form */ if ( D == 0 ) { if ( Np ) if ( fread( lpcoef, sizeof(float), Np+1, stdin ) == 0 ) eof = 1 ; if ( fread( channel, sizeof(float), N+2, stdin ) == 0 ) eof = 1 ; } else { eof = shiftin( input, Nw, D ) ; fprintf( stderr, "%d=%.3fs (%.3g)/", in, (float)in/R, maxof( &input[Nw-D], D ) ) ; if ( Np ) { vvmult( winput, Hwin, input, Nw ) ; lpcoef[0] = lpa( winput, Nw, lpcoef, Np ) ; fprintf( stderr, "%.3g/", lpcoef[0] ) ; } fold( input, Wanal, Nw, buffer, N, in ) ; rfft( buffer, N2, FORWARD ) ; convert( buffer, channel, N2, D, R ) ; } if ( I == 0 ) { if ( Np ) fwrite( lpcoef, sizeof(float), Np+1, stdout ) ; fwrite( channel, sizeof(float), N+2, stdout ) ; fflush( stdout ) ; fprintf( stderr, "\n" ) ; fflush( stderr ) ; continue ; } /* * at this point channel[2*i] contains amplitude data and * channel[2*i+1] contains frequency data (in Hz) for phase * vocoder channels i = 0, 1, ... N/2; the center frequency * associated with each channel is i*f, where f is the * fundamental frequency of analysis R/N; any desired spectral * modifications can be made at this point: pitch modifications * are generally well suited to oscillator bank resynthesis, * while time modifications are generally well (and more * efficiently) suited to overlap-add resynthesis */ if ( obank ) { /* * oscillator bank resynthesis */ oscbank( channel, N2, lpcoef, Np, R, Nw, I, P, output ) ; fprintf( stderr, "%d=%.3fs (%.3g)\n", on, (float)on/R, maxof( output, I ) ) ; fflush( stderr ) ; shiftout( output, Nw, I, on+Nw-I ) ; } else { /* * overlap-add resynthesis */ unconvert( channel, buffer, N2, I, R ) ; rfft( buffer, N2, INVERSE ) ; overlapadd( buffer, N, Wsyn, output, Nw, on ) ; fprintf( stderr, "%d=%.3fs (%.3g)\n", on, (float)on/R, maxof( output, I ) ) ; fflush( stderr ) ; shiftout( output, Nw, I, on ) ; } } /* Release the DSP */ DSPAPFree() ; exit( 0 ) ; } void vvmult( float *out, float *a, float *b, int n ) { register float *lim = out + n ; while ( out < lim ) *out++ = *a++ * *b++ ; } float maxof( float *a, int n ) { register float *lim = a + n, m ; for ( m = *a++ ; a < lim ; a++ ) if ( *a > m ) m = *a ; return( m ) ; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.