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; }
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; }
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; }