Ejemplo n.º 1
0
static void *xtract_new(t_symbol *me, t_int argc, t_atom *argv) {
    
    t_xtract_tilde *x = (t_xtract_tilde *)pd_new(xtract_class);
    xtract_mel_filter *mf;
    t_int n, N, M, f, F, 
          n_args, 
          type;
    t_float *argv_max;
    t_symbol *arg1;
    xtract_function_descriptor_t *fd;
    char *p_name, 
         *p_desc, 
         *author;
    int year;

    p_name = p_desc = author = NULL;
   
    n_args = type = 0;

    f = F = XTRACT_FEATURES;

    N = BLOCKSIZE;
    
    x->argv = NULL;
    x->argv_type = 0;
    x->done_init = 0;
    x->is_scalar = 0;
    x->is_subframe = 0;
    x->feature = -1;
    
    /* Allocate data area */
    x->data = (double *)getbytes(N * sizeof(double));
    x->result = (double *)getbytes(N * sizeof(double));

    /* Parse arguments */
    if(argc){
        arg1 = atom_getsymbol(argv);
        if(arg1 == gensym("subframe"))
            x->is_subframe = 1;
        else
            x->feature_name = atom_getsymbol(argv);
    }
    else {
	post("xtract~: No arguments given");
        return (void *)x;
    }
    if(argc > 1){
        if(x->is_subframe)
            x->feature_name = atom_getsymbol(argv+1);
        else
            N = atom_getint(argv+1);
    }
    if(argc > 2)
        N = atom_getint(argv+2);

    x->init_blocksize = N;
    M = N >> 1;

    /* get function descriptors */
    fd = (xtract_function_descriptor_t *)xtract_make_descriptors();

    /* iterate over descriptors */
    while(f--){
	/* map creation arg to feature */
	if(x->feature_name == gensym(fd[f].algo.name)){ 
	    x->feature = f;
	    break;
	}
    }

    if(x->feature == -1)
        post("xtract~: feature not found: %s", x->feature_name->s_name);

    /* allocate memory for feature arguments */
    n_args = fd[f].argc;
    type = fd[f].argv.type;

    x->argv_type = type;

    if(n_args){
	for(n = 0; n < n_args; n++){
		    argv_max = &fd[f].argv.max[n]; 
		    /*post("Argument %d, max: %.2f", n, *argv_max); */
	}
	if(type == XTRACT_MEL_FILTER){
	    x->memory.argv = (size_t)(n_args * sizeof(xtract_mel_filter));
	    x->argv = (xtract_mel_filter *)getbytes(x->memory.argv);
	}
	else if(type == XTRACT_INT){
	    x->memory.argv = (size_t)(n_args * sizeof(t_int));
	    x->argv = (t_int *)getbytes(x->memory.argv);
	}
	else if (type == XTRACT_FLOAT){
	    x->memory.argv = (size_t)(n_args * sizeof(t_float));
	    x->argv = (t_float *)getbytes(x->memory.argv);
	}
	else
	    x->memory.argv = 0;
    }

    p_name = fd[f].algo.p_name;
    p_desc = fd[f].algo.p_desc;
    author = fd[f].algo.author;
    year = fd[f].algo.year; 

    if(argc){
	if(strcmp(p_name, ""))	
	    post("xtract~: %s", p_name );
	if(strcmp(p_desc, ""))	
	    post("xtract~: %s", p_desc );
	if(strcmp(author, "") && year)	
	    post("xtract~: %s(%d)", author, year);
    }	
    
    /* Adjust frame size if we are using subframe features */
    if(x->is_subframe)
        N = M;

    post("xtract~: window size: %d", N);

    /* do init if needed */
    if(x->feature == XTRACT_MFCC){

        mf = x->argv;
        
        mf->n_filters = 20;
        
        post("xtract~: mfcc: filters = %d", 
		((xtract_mel_filter *)x->argv)->n_filters);
        mf->filters = 
            (t_float **)getbytes(mf->n_filters * sizeof(t_float *));
        for(n = 0; n < mf->n_filters; n++)
            mf->filters[n] = (float *)getbytes(N * sizeof(float));
                 
        xtract_init_mfcc(N, NYQUIST, XTRACT_EQUAL_GAIN, 80.0f,
                18000.0f, mf->n_filters, mf->filters);
        x->done_init = 1;
    }
    else if(x->feature == XTRACT_BARK_COEFFICIENTS){
        xtract_init_bark(N, NYQUIST, x->argv);
        x->done_init = 1;
    }
    else if(x->feature == XTRACT_WINDOWED){
        x->window = xtract_init_window(N, XTRACT_HANN);
        x->argv = x->window;
        x->done_init = 1;
    }

    /* Initialise fft_plan if required */
    if(x->feature == XTRACT_AUTOCORRELATION_FFT ||
            x->feature == XTRACT_SPECTRUM ||
            x->feature == XTRACT_DCT){
        xtract_init_fft(N, x->feature);
        x->done_init = 1;
    }
    
    if(fd[f].is_scalar)
	x->is_scalar = 1;

/* 
    if(x->feature == XTRACT_AUTOCORRELATION || 
	    x->feature == XTRACT_AUTOCORRELATION_FFT || 
	    x->feature == XTRACT_MFCC || x->feature == XTRACT_AMDF || 
	    x->feature == XTRACT_ASDF|| x->feature == XTRACT_DCT || 
	    x->feature == XTRACT_BARK_COEFFICIENTS || 
	    x->feature == XTRACT_SPECTRUM || 
	    x->feature == XTRACT_PEAK_SPECTRUM || 
	    x->feature == XTRACT_HARMONIC_SPECTRUM ||
            x->feature == XTRACT_LPC ||
            x->feature == XTRACT_LPCC ||
            x->feature == XTRACT_WINDOWED) 
	x->feature_type = XTRACT_VECTOR;
        */              
  /*  else if (x->feature == XTRACT_FLUX || x->feature == XTRACT_ATTACK_TIME || 
            x->feature == XTRACT_DECAY_TIME || x->feature == XTRACT_DIFFERENCE_VECTOR) 
        x->feature_type = XTRACT_DELTA; */
/*       
    else x->feature_type = XTRACT_SCALAR;
*/

    /* argv through right inlet */
    inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("list"), gensym("list"));

    /* if feature is vector, create signal out */
    if(!x->is_scalar) 
        outlet_new(&x->x_obj, &s_signal);

    /* otherwise: float */
    else 
        outlet_new(&x->x_obj, &s_float);

    if(x->is_scalar && x->is_subframe)
        post(
        "xtract~: warning: subframes not yet supported for scalar features");
    
    /* free the function descriptors */
    xtract_free_descriptors(fd);
    
    return (void *)x;
}
double* extractall(double* wavetable, long numFrames, double samplerate){



    long size = 38+5*BLOCKSIZE+MFCC_FREQ_BANDS;
    double *FVec = (double*) malloc(size*sizeof(double));
    long count=0;
    long i,n,j,k;
    int rv = XTRACT_SUCCESS;
    xtract_mel_filter mel_filters;

    /* get the F0 */
    xtract[XTRACT_WAVELET_F0](wavetable, BLOCKSIZE, &samplerate, &f0);
    FVec[count++] = f0;
    
    //* get the F0 as a MIDI note 
    xtract[XTRACT_MIDICENT](NULL, 0, &f0, &midicents);
    FVec[count++] = midicents;

    //* get the mean of the input 
    xtract[XTRACT_MEAN](wavetable, BLOCKSIZE, NULL, &mean);
    FVec[count++] = mean;

    //MY-VARIANCE
    xtract[XTRACT_VARIANCE](wavetable, BLOCKSIZE, &mean, &variance);
    FVec[count++] = variance;

    //MY-STANDARD DEVIATION
    xtract[XTRACT_STANDARD_DEVIATION](wavetable, BLOCKSIZE, &variance, &stdDeviation);
    FVec[count++] = stdDeviation;

    //MY-AVERAGE DEVIATION
    xtract[XTRACT_AVERAGE_DEVIATION](wavetable, BLOCKSIZE, &mean, &avgDeviation);
    FVec[count++] = avgDeviation;

    //MY-SKEWNESS
    argd[0] = mean;
    argd[1] = stdDeviation;

    xtract[XTRACT_SKEWNESS](wavetable, BLOCKSIZE, argd, &skewness);
    FVec[count++] = skewness;

    //MY-KURTOSIS
    xtract[XTRACT_KURTOSIS](wavetable, BLOCKSIZE, argd, &kurtosis);
    FVec[count++] = kurtosis;

    //MY-ZERO CROSSING RATE
    xtract[XTRACT_ZCR](wavetable, BLOCKSIZE, NULL, &zcr);
    FVec[count++] = zcr;

    //MY-RMS AMPLITUDE
    xtract[XTRACT_RMS_AMPLITUDE](wavetable, BLOCKSIZE, NULL, &rmsAmplitude);
    FVec[count++] = rmsAmplitude;

    //MY-HIGHEST VALUE
    xtract[XTRACT_HIGHEST_VALUE](wavetable, BLOCKSIZE, NULL, &highestValue);
    FVec[count++] = highestValue;

    //MY-SUM
    xtract[XTRACT_SUM](wavetable, BLOCKSIZE, NULL, &sum);
    FVec[count++] = sum;

    //MY-CREST
    argd[0] = mean;
    argd[1] = highestValue;
    xtract[XTRACT_CREST](wavetable, BLOCKSIZE, argd, &crest);
    FVec[count++] = crest;

    //* get the lowest value in the input 
    argd[0] = -.5;
    rv = xtract[XTRACT_LOWEST_VALUE](wavetable, BLOCKSIZE, argd, &lowest);
    FVec[count++] = lowest;

    //MY-AMDF
    xtract[XTRACT_AMDF](wavetable, BLOCKSIZE, NULL, amdf);
    for(k=0;k<BLOCKSIZE;k++)
	FVec[i++] = amdf[k];

    //MY-ASDF
    xtract[XTRACT_ASDF](wavetable, BLOCKSIZE, NULL, asdf);
    for(k=0;k<BLOCKSIZE;k++)
	FVec[i++] = asdf[k];

    //MY-DCT
    xtract[XTRACT_DCT](wavetable, BLOCKSIZE, NULL, dct);
    for(k=0;k<BLOCKSIZE;k++)
	FVec[i++] = dct[k];

    //* create the window function 
    window = xtract_init_window(BLOCKSIZE, XTRACT_HANN);
    xtract_windowed(wavetable, BLOCKSIZE, window, windowed);
    xtract_free_window(window);

    //* get the spectrum 
    argd[0] = SAMPLERATE / (double)BLOCKSIZE;
    argd[1] = XTRACT_MAGNITUDE_SPECTRUM;
    argd[2] = 0.f; //* DC component - we expect this to zero for square wave 
    argd[3] = 0.f; //* No Normalisation 

    xtract_init_fft(BLOCKSIZE, XTRACT_SPECTRUM);
    xtract[XTRACT_SPECTRUM](windowed, BLOCKSIZE, &argd[0], spectrum);
    xtract_free_fft();

    //MY_BARK
//    xtract_init_bark(BLOCKSIZE,samplerate,barkCoeff);
//    xtract[XTRACT_BARK_COEFFICIENTS](spectrum,BLOCKSIZE,barkCoeff,bark);


    //MY-SPECTRAL MEAN
    xtract[XTRACT_SPECTRAL_MEAN](spectrum, BLOCKSIZE, NULL, &specMean);
    FVec[count++] = specMean;

    //MY-SPECTRAL VARIANCE
    xtract[XTRACT_SPECTRAL_VARIANCE](spectrum, BLOCKSIZE, &specMean, &specVariance);
    FVec[count++] = specVariance;

    //MY-SPECTRAL STANDARD DEVIATION
    xtract[XTRACT_SPECTRAL_STANDARD_DEVIATION](spectrum, BLOCKSIZE, &specMean, &specStdDeviation);
    FVec[count++] = specStdDeviation;

    //xtract[XTRACT_SPECTRAL_AVERAGE_DEVIATION](spectrum, BLOCKSIZE, &specMean, &specAvgDeviation);
    //FVec[count++] = specAvgDeviation;

    //MY-SPECTRAL SKEWNESS
    argd[0] = specMean;
    argd[1] = specStdDeviation;
    xtract[XTRACT_SPECTRAL_SKEWNESS](spectrum, BLOCKSIZE, argd, &specSkewness);
    FVec[count++] = specSkewness;

    //MY-SPECTRAL KURTOSIS
    xtract[XTRACT_SPECTRAL_KURTOSIS](spectrum, BLOCKSIZE, argd, &specKurtosis);
    FVec[count++] = specKurtosis;

    xtract[XTRACT_SPECTRAL_CENTROID](spectrum, BLOCKSIZE, NULL, &centroid);
    FVec[count++] = centroid;

    //MY-POWER
    xtract[XTRACT_POWER](spectrum, BLOCKSIZE, NULL, &power);
    FVec[count++] = power;

    //MY-SHARPNESS
    xtract[XTRACT_SHARPNESS](spectrum, BLOCKSIZE, NULL, &sharpness);
    FVec[count++] = sharpness;

    //MY-SPECTRAL SLOPE
    xtract[XTRACT_SPECTRAL_SLOPE](spectrum, BLOCKSIZE/2, NULL, &specSlope);
    FVec[count++] = specSlope;

    //MY-HPS
    xtract[XTRACT_HPS](spectrum, BLOCKSIZE, NULL, &hps);
    FVec[count++] = hps;

    //MY-FLATNESS
    xtract[XTRACT_FLATNESS](spectrum, BLOCKSIZE, NULL, &flatness);
    FVec[count++] = flatness;

    //MY-TONALITY
    xtract[XTRACT_TONALITY](NULL, NULL, &flatness, &tonality);
    FVec[count++] = tonality;


    argd[0] = SAMPLERATE / (double)BLOCKSIZE;
    argd[1] = 10.0; //* peak threshold as %  of maximum peak 
    xtract[XTRACT_PEAK_SPECTRUM](spectrum, BLOCKSIZE / 2, argd, peaks);

    argd[0] = f0;
    argd[1] = .3; //* harmonic threshold 
    xtract[XTRACT_HARMONIC_SPECTRUM](peaks, BLOCKSIZE, argd, harmonics);

    //MY-ODD EVEN RATIO
    xtract[XTRACT_ODD_EVEN_RATIO](harmonics, BLOCKSIZE, NULL, &oddEvenRatio);
    FVec[count++] = oddEvenRatio;

    //MY-TRISTIMULUS-1
    xtract[XTRACT_TRISTIMULUS_1](harmonics, BLOCKSIZE, NULL, &tristimulus1);
    FVec[count++] = tristimulus1;

    //MY-TRISTIMULUS-2
    xtract[XTRACT_TRISTIMULUS_2](harmonics, BLOCKSIZE, NULL, &tristimulus2);
    FVec[count++] = tristimulus2;

    //MY-TRISTIMULUS-2
    xtract[XTRACT_TRISTIMULUS_3](harmonics, BLOCKSIZE, NULL, &tristimulus3);
    FVec[count++] = tristimulus3;

    //MY-NOISINESS
    xtract[XTRACT_NOISINESS](NULL, NULL, harmonics, &noisiness);
    FVec[count++] = noisiness;
    
    //MY-SPECTRAL INHARMONICITY
//    xtract[XTRACT_SPECTRAL_INHARMONICITY](peaks, BLOCKSIZE, &f0, &specInharmonicity);
//    FVec[count++] = specInharmonicity; 

    //MY-SPERAD
//    xtract[XTRACT_SPREAD](spectrum, BLOCKSIZE, NULL, &spread);
//    FVec[count++] = spread;

    //MY-AUTOCORRELATION and AUTOCORRELATION FFT
//    xtract[XTRACT_AUTOCORRELATION](wavetable, BLOCKSIZE, NULL, &autocorrelation);
//    FVec[count++] = autocorrelation;
//    printf("\nAutocorrelation : %f\n", autocorrelation);

    //xtract[XTRACT_AUTOCORRELATION_FFT](wavetable, BLOCKSIZE, NULL, &autocorrelationFFT);
    //FVec[count++] = autocorrelationFFT;


    for(k=0;k<BLOCKSIZE;k++)
	FVec[i++] = spectrum[k];

    //* compute the MFCCs 
    mel_filters.n_filters = MFCC_FREQ_BANDS;
    mel_filters.filters   = (double **)malloc(MFCC_FREQ_BANDS * sizeof(double *));
    for(n = 0; n < MFCC_FREQ_BANDS; ++n)
    {
        mel_filters.filters[n] = (double *)malloc(BLOCKSIZE * sizeof(double));
    }

    xtract_init_mfcc(BLOCKSIZE >> 1, SAMPLERATE >> 1, XTRACT_EQUAL_GAIN, MFCC_FREQ_MIN, MFCC_FREQ_MAX, mel_filters.n_filters, mel_filters.filters);
    xtract_mfcc(spectrum, BLOCKSIZE >> 1, &mel_filters, mfccs);

    for(k=0;k<MFCC_FREQ_BANDS;k++)
	FVec[i++] = mfccs[k];


    //* compute Spectral Flux 
    argd[0] = SAMPLERATE / (BLOCKSIZE/2);
    argd[1] = XTRACT_MAGNITUDE_SPECTRUM;
    argd[2] = 0.f; //* DC component 
    argd[3] = 0.f; //* No Normalisation 
    
    xtract_init_fft(BLOCKSIZE/2, XTRACT_SPECTRUM);
    xtract_features_from_subframes(wavetable, BLOCKSIZE, XTRACT_SPECTRUM, argd, subframes);
    xtract_difference_vector(subframes, BLOCKSIZE, NULL, difference);
    
    argd[0] = 1.0; //* norm order 
    argd[1] = XTRACT_POSITIVE_SLOPE; //* positive slope 
    
    xtract_flux(difference, BLOCKSIZE/2, argd, &flux);
    FVec[i++] = flux;


    for(k=0;k<BLOCKSIZE;k++)
	FVec[i++] = peaks[k];


/*
    printf("\nF0: %f\n", f0);
    printf("\nMIDI cents: %f\n", midicents);
    printf("\nInput mean = %.5f\t%.5f\n", mean); //* We expect this to be zero for a square wave 
    printf("\nVariance = %f\n",variance);
    printf("\nStandard Deviation = %f\n",stdDeviation);
    printf("\nAverage Deviation = %f\n",avgDeviation);
    printf("\nSkewness = %f\n",skewness);
    printf("\nKurtosis = %f\n",kurtosis);
    printf("\nZero Crossing Rate = %f\n",zcr);
    printf("\nRMS Amplitude = %f\n",rmsAmplitude);
    printf("\nHighest Value = %f\n",highestValue);
    printf("\nSum = %f\n", sum);
    printf("\nCrest = %f\n", crest);
    printf("\nLowest value = %.6f\n\n", lowest);
    for(n=0;n<BLOCKSIZE;n+=50)
	printf("\nAMDF[%d]: %f",n,amdf[n]);
    for(n=0;n<BLOCKSIZE;n+=50)
	printf("\nASDF[%d]: %f",n,asdf[n]);
    for(n=0;n<BLOCKSIZE;n+=50)
	printf("\nDCT[%d]: %f",n,dct[n]);
//    for(n=0;n<BLOCKSIZE;n+=1000)
//	printf("\nBARK[%d]: %f",n,bark[n]);
    printf("\nSpectral Mean: %f\n", specMean);
    printf("\nSpectral Variance: %f\n", specVariance);
    printf("\nSpectral Standard Deviation: %f\n", specStdDeviation);
    //printf("\nSpectral Average Deviation: %f\n", specAvgDeviation);
    printf("\nSpectral Skewness: %f\n", specSkewness);
    printf("\nSpectral Kurtosis: %f\n", specKurtosis);
    printf("\nSpectral Centroid: %f\n", centroid);
    printf("\nPower = %f\n",power);
    printf("\nSharpness = %f\n",sharpness);
    printf("\nSpectral Slope = %f\n",specSlope);
    printf("\nHPS = %f\n",hps);
    printf("\nFlatness: %f\n", flatness);
    printf("\nTonality: %f\n", tonality);
    printf("\nOdd Even Ratio : %f\n", oddEvenRatio);
    printf("\nTristimulus-1 : %f\n", tristimulus1);
    printf("\nTristimulus-2 : %f\n", tristimulus2);
    printf("\nTristimulus-3 : %f\n", tristimulus3);
    printf("\nNoisiness : %f\n", noisiness);
//    printf("\nSpectral Inharmonicity : %f\n", specInharmonicity);
//    printf("\nSpread : %f\n", spread);
//    printf("\nAutocorrelation fft : %f\n",autocorrelationFFT);
    printf("\nSpectrum:\n");
    for(n = 0; n < (BLOCKSIZE >> 1); n+=1000)
    {
        printf("freq: %.1f\tamp: %.6f", spectrum[n + (BLOCKSIZE >> 1)], spectrum[n]);
        if (peaks[n + (BLOCKSIZE >> 1)] != 0.f)
        {
            printf("\tpeak:: freq: %.1f\tamp: %.6f\n", peaks[n + (BLOCKSIZE >> 1)], peaks[n]);
        }
        else
        {
            printf("\n");
        }
    }
    printf("\n");
    printf("MFCCs:\n");
    for(n = 0; n < MFCC_FREQ_BANDS; ++n)
    {
        printf("band: %d\t", n);
        if(n < 10) {
            printf("\t");
        }
        printf("coeff: %f\n", mfccs[n]);
    }
    printf("Flux: %f\n", flux);*/



//}
    // cleanup 
    for(n = 0; n < MFCC_FREQ_BANDS; ++n)
    {
        free(mel_filters.filters[n]);
    }
    free(mel_filters.filters);

    return FVec;


}