map<char, vector<double> > soundFeatures::calcFeatures(string featString, int windowStart, int windowLength){
    double mean, dev, zcr, hzcrr, kurtosis, skewness, variance, RMS, sharp, lpcc_order, loud;
    double s_var ,s_mean, s_dev, s_kur, s_skew, s_centroid;
    double spectrum[windowLength], autoCorr[windowLength+1], lpc[20], lpcc[15], mfcc[40], barkC[25];
    int bark[26];

    xtract_mel_filter mfccBank;

    map <string, bool> calcFeat;

    for(int k = 0; k < featString.size(); k++){
        switch (featString[k]){
            case 'a' :
            case 'b' :
                if(!calcFeat["zcr"]){
                    xtract[XTRACT_ZCR](wavData + windowStart, windowLength, NULL, &zcr);
                    calcFeat["zcr"] = true;
                }
                if(featString[k]== 'a') result['a'] = vector<double>{zcr};

                if(featString[k]== 'b'){
                    double tempZRC;
                    double tempRes=0;
                    double tempN= windowLength / subWindow;
                    double tempAvg= zcr;
                    for (int i=0; i < windowLength ; i+=subWindow){
                        xtract[XTRACT_ZCR](wavData+i+windowStart, subWindow, NULL, &tempZRC);
                        if (tempZRC > 1.5 * tempAvg) tempRes++;
                        }
                    hzcrr = tempRes / (2*tempN);
                    result['b'] = vector<double>{hzcrr};
                }
            break;
            case 'c':
            case 'd':
                if(!calcFeat["scalars"]){
                    xtract[XTRACT_MEAN](wavData + windowStart, windowLength, NULL, &mean);
                    xtract[XTRACT_VARIANCE](wavData + windowStart, windowLength, &mean, &variance);
                    xtract[XTRACT_STANDARD_DEVIATION](wavData + windowStart, windowLength, &variance, &dev);
                    calcFeat["scalars"] = true;
                    }
                if(featString[k]== 'c'){
                    double temp_sca[2]={mean, dev};
                    xtract[XTRACT_KURTOSIS](wavData + windowStart, windowLength, temp_sca , &kurtosis);
                    result['c'] = vector<double>{kurtosis};
                    }
                if(featString[k]== 'd'){
                    double temp_sca[2]={mean, dev};
                    xtract[XTRACT_SKEWNESS](wavData + windowStart, windowLength, temp_sca, &skewness);
                    result['d'] = vector<double>{skewness};
                    }
            break;
            case 'e':
            case 'f':
            case 'g':
            case 'h':
            case 'i':
            case 'j':
            case 'k':
                if (!calcFeat["spectrum"]){
                    double temp1[4] = {(double)samplerate/windowLength, XTRACT_MAGNITUDE_SPECTRUM, 0.0f, 0.0f};
                    xtract_init_fft(windowLength, XTRACT_SPECTRUM);
                    xtract[XTRACT_SPECTRUM](wavData + windowStart, windowLength, &temp1[0], &spectrum[0]);
                    xtract_free_fft();

                    xtract[XTRACT_SPECTRAL_MEAN](spectrum, windowLength, NULL, &s_mean);
                    xtract[XTRACT_SPECTRAL_VARIANCE](spectrum, windowLength, &s_mean, &s_var);
                    xtract[XTRACT_SPECTRAL_STANDARD_DEVIATION](spectrum, windowLength, &s_var, &s_dev);
                    calcFeat["spectrum"] = true;
                    }
                if(featString[k]== 'e') result['e'] = vector<double>{s_mean};
                if(featString[k]== 'f') result['f'] = vector<double>{s_var};
                if(featString[k]== 'g') result['g'] = vector<double>{s_dev};

                {//radi odvajanja deklaracije temp unutar samo ovog bloka
                double temp[2] = {s_mean, s_dev};
                if(featString[k]== 'h'){
                    xtract[XTRACT_SPECTRAL_CENTROID](spectrum, windowLength,  NULL, &s_centroid);
                    result['h'] = vector<double>{s_centroid};
                    }
                if(featString[k]== 'i'){
                    xtract[XTRACT_SPECTRAL_KURTOSIS](spectrum, windowLength,  temp, &s_kur);
                    result['i'] = vector<double>{s_kur};
                    }
                if(featString[k]== 'j'){
                    xtract[XTRACT_SPECTRAL_SKEWNESS](spectrum, windowLength,  temp, &s_skew);;
                    result['j'] = vector<double>{s_skew};
                    }
                if(featString[k]== 'k'){
                    xtract[XTRACT_SHARPNESS](spectrum, windowLength/2,  NULL, &sharp);
                    result['k'] = vector<double>{sharp};
                    }
                }
            break;
            case 'l':
                if (!calcFeat["spectrum"]){
                    double temp1[4] = {(double)samplerate/windowLength, XTRACT_MAGNITUDE_SPECTRUM, 0.0f, 0.0f};
                    xtract_init_fft(windowLength, XTRACT_SPECTRUM);
                    xtract[XTRACT_SPECTRUM](wavData + windowStart, windowLength, &temp1[0], &spectrum[0]);
                    xtract_free_fft();

                    calcFeat["spectrum"] = true;
                }
                xtract_init_bark(windowLength/2, samplerate, bark);
                xtract[XTRACT_BARK_COEFFICIENTS](spectrum, windowLength/2, bark, barkC);
                calcFeat["bark"] = true;

                xtract[XTRACT_LOUDNESS](barkC, 10, NULL, &loud);
                result['l'] = vector<double>{loud};
            break;
            case 'm':
                xtract[XTRACT_RMS_AMPLITUDE](wavData + windowStart, windowLength, NULL, &RMS);
                result['m'] = vector<double>{RMS};
            break;
            case 'n':
                xtract[XTRACT_AUTOCORRELATION](wavData + windowStart, windowLength, NULL, autoCorr);
                xtract[XTRACT_LPC](autoCorr, 20, NULL, lpc);
                //lpcc_order = 15;
                //xtract[XTRACT_LPCC](lpc + 10, 10, &lpcc_order, lpcc);
                //result['n'] = vector<double>(lpcc, lpcc + (int)lpcc_order);
                result['n'] = vector<double>(lpc+20, lpc + 40);
            break;
            case 'o':
                if (!calcFeat["spectrum"]){
                double temp1[4] = {(double)samplerate/windowLength, XTRACT_MAGNITUDE_SPECTRUM, 0.0f, 0.0f};
                xtract_init_fft(windowLength, XTRACT_SPECTRUM);
                xtract[XTRACT_SPECTRUM](wavData + windowStart, windowLength, &temp1[0], &spectrum[0]);
                xtract_free_fft();

                calcFeat["spectrum"] = true;
                }

                mfccBank.n_filters = 40;
                mfccBank.filters = (double **)malloc(40 * sizeof(double *));
                for(int i = 0; i < 40; i++)
                    mfccBank.filters[i] = (double *)malloc(windowLength * sizeof(double));

                xtract_init_mfcc(windowLength/2, samplerate/2, XTRACT_EQUAL_GAIN, 20, samplerate/2, mfccBank.n_filters, mfccBank.filters);

                xtract[XTRACT_MFCC](spectrum, windowLength/2, &mfccBank, mfcc);

                for(int i = 0; i < 40; ++i)
                    free(mfccBank.filters[i]);
                free(mfccBank.filters);

                result['o'] = vector<double>(mfcc, mfcc + 40);
            break;
            case 'p':
                if (!calcFeat["bark"]){
                    if (!calcFeat["spectrum"]){
                        double temp1[4] = {(double)samplerate/windowLength, XTRACT_MAGNITUDE_SPECTRUM, 0.0f, 0.0f};
                        xtract_init_fft(windowLength, XTRACT_SPECTRUM);
                        xtract[XTRACT_SPECTRUM](wavData + windowStart, windowLength, &temp1[0], &spectrum[0]);
                        xtract_free_fft();

                        calcFeat["spectrum"] = true;
                    }
                    xtract_init_bark(windowLength/2, samplerate, bark);
                    xtract[XTRACT_BARK_COEFFICIENTS](spectrum, windowLength/2, bark, barkC);
                    calcFeat["bark"] = true;
                    }
                result['p'] = vector<double>(barkC, barkC + 24);
            break;
        }
    }
    return result;
}
Example #2
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;
}
Example #3
0
static void *xtract_tilde_new(t_symbol *me, t_int argc, t_atom *argv) {
    
    t_symbol *tmp;
    t_xtract_tilde *x = (t_xtract_tilde *)newobject(xtract_tilde_class);
    xtract_mel_filter *mf;
    t_int n, N, f, F, n_args, type;
    t_float *argv_max;
    xtract_function_descriptor_t *fd;
    char *p_name, *p_desc, *author;
    int year;

    tmp = NULL;
    p_name = p_desc = author = NULL;
   
    n_args = type = x->feature = 0;

    f = F = XTRACT_FEATURES;

    N = BLOCKSIZE;
    
    x->argv = NULL;
    x->done_init = 0;
    
    if(argc)
	tmp = argv[0].a_w.w_sym; /*atom_getsymbol(argv); */
    if(argc > 1)
	N = (t_int)argv[1].a_w.w_long;

    x->init_blocksize = N;

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

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

    /* allocate memory for feature arguments */
    n_args = fd[f].argc;
    type = fd[f].argv.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);
    }	
    else
	post("xtract~: No arguments given");
    
    /* 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);
    }
    else if(x->feature == XTRACT_BARK_COEFFICIENTS)
        xtract_init_bark(N, NYQUIST, x->argv);
    
    /* 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(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_type = XTRACT_VECTOR;
                
    else if (x->feature == XTRACT_FLUX || x->feature == XTRACT_ATTACK_TIME || 
            x->feature == XTRACT_DECAY_TIME || x->feature == XTRACT_DELTA) 
        x->feature_type = XTRACT_DELTA;
       
    else x->feature_type = XTRACT_SCALAR;

    /* argv through right inlet */
    inlet_new((t_pxobject *)x, "list"); 

    /* DSP inlet */
    dsp_setup((t_pxobject *)x, 1);


    /* if feature is vector, create signal out */
    if(x->feature_type == XTRACT_VECTOR)  
	outlet_new((t_pxobject *)x, "signal");

    /* otherwise: float */
    else 
	x->outlet = floatout((t_pxobject *)x);

    
    /* free the function descriptors */
    xtract_free_descriptors(fd);
    
    return (void *)x;
}