DATASET *make_data(int points, double noise) { int i; double x, y; SERIES *ser; DATASET *data; ser = series_create(); ser->y_width = ser->x_delta = ser->y_delta = ser->offset = 1; ser->x_width = 2; ser->step = 3; /* Fill up a SERIES with 'points' patterns that consists of a single * input, and 'nout' outputs. Each output is a successive delay from * the logistic map. */ for(i = 0; i < points; i++) { x = random_range(-1, 1); y = random_range(-1, 1); series_append_val(ser, x); series_append_val(ser, y); series_append_val(ser, sin(5 * x * y) + y); } data = dataset_create(&dsm_series_method, ser); return(data); }
fextract_series_t *getOnlyCoG(dsp_sample_t *signal, int nframes) { int n_samples, offset=0, frames=0, i; dsp_sample_t s[MAX_SAMPLES], last_s[MAX_SAMPLES]; dsp_sample_t *frame, *last_frame, *__tmp; mx_real_t *window; mx_complex_t *z; fextract_series_t *serie=NULL; serie=series_create(MAX_SERIES); frame = s; last_frame = last_s; window = (mx_real_t *) rs_malloc(sizeof(mx_real_t) * SP_FRAME_LEN, "w"); z = (mx_complex_t *) rs_malloc(sizeof(mx_complex_t) * SP_FRAME_LEN, "z"); n_samples = next_mfcc_frame(frame, NULL, SP_FRAME_LEN, SP_FRAME_RATE, signal,nframes); offset += SP_FRAME_LEN; while (n_samples > 0) { if (n_samples < SP_FRAME_LEN) break; frames++; // FFT: ev. mit prae-emphase und zero-padding /* ... Hamming-Fenstern ... */ dsp_window_hamming(window, frame, SP_FRAME_LEN); for (i = 0; i < SP_FRAME_LEN; i++) { mx_re(z[i]) = window[i]; mx_im(z[i]) = 0.0; } /* FFT */ dsp_xfft(z, SP_FRAME_LEN, 0); series_add(serie,get_CoG(z,SP_FRAME_LEN)); /* ... und naechsten Frame einlesen */ __tmp = last_frame; last_frame = frame; frame = __tmp; n_samples = next_mfcc_frame(frame, last_frame, SP_FRAME_LEN, SP_FRAME_RATE, signal+offset,nframes-offset); offset += SP_FRAME_RATE; } rs_free(window); rs_free(z); return serie; }
int getVoicingFeatures(mx_real_t *features, mx_real_t *pitch, int nframes) { int i, voiced_length=0, unvoiced_length=0, fcount=0; fextract_series_t *vseries = series_create(MAX_SERIES); fextract_series_t *useries = series_create(MAX_SERIES); if (nframes <=0) { for (i=0;i<N_VOICING_FEATURES;i++) features[fcount++]=-1; return fcount; } for (i=0;i<nframes-1;i++) { if (pitch[i]!=0) voiced_length++; else unvoiced_length++; if (i>0 && pitch[i-1] !=0 && pitch[i]==0) { series_add(vseries,voiced_length); voiced_length=0; } if (i>0 && pitch[i-1] ==0 && pitch[i]!=0) { series_add(useries,unvoiced_length); unvoiced_length=0; } } if (pitch[nframes-1]!=0) series_add(vseries,++voiced_length); else series_add(useries,++unvoiced_length); fcount+=getStatistics(features+fcount,vseries->series,vseries->nSeries); fcount+=getStatistics(features+fcount,useries->series,useries->nSeries); features[fcount++]=1.0*vseries->nSeries/nframes; series_destroy(vseries); series_destroy(useries); return fcount; }
fextract_series_t* getPeaks (fextract_series_t *pulses, mx_real_t *signal, int nsamples, mx_real_t pmin, mx_real_t pmax, mx_real_t maximumPeriodFactor) { int i, imin=0, imax=pulses->nSeries-1, numberOfPeaks=pulses->nSeries; fextract_series_t *peaks; if (numberOfPeaks < 3) return NULL; peaks = series_create(MAX_SERIES); for (i = imin + 1; i < imax; i ++) { mx_real_t p1 = pulses->series [i] - pulses->series [i - 1]; mx_real_t p2 = pulses->series [i + 1] - pulses->series [i]; mx_real_t intervalFactor = p1 > p2 ? p1 / p2 : p2 / p1; if (pmin == pmax || (p1 >= pmin && p1 <= pmax && p2 >= pmin && p2 <= pmax && intervalFactor <= maximumPeriodFactor)) { mx_real_t peak = getHannWindowedRms (signal, nsamples, pulses->series [i], 0.2 * p1, 0.2 * p2); if (peak != MX_REAL_MAX && peak > 0.0) { series_add(peaks,pulses->series[i]); series_add(peaks,peak); } } } return peaks; }
DATASET *make_data(int points) { int i; double x1, x2; SERIES *ser; DATASET *data; ser = series_create(); ser->x_width = ser->y_width = 2; ser->x_delta = ser->y_delta = ser->offset = 1; ser->step = 4; for(i = 0; i < points; i++) { x1 = random_range(-1, 1); x2 = random_range(-1, 1); series_append_val(ser, x1); series_append_val(ser, x2); series_append_val(ser, f1(x1, x2)); series_append_val(ser, f2(x1, x2)); } data = dataset_create(&dsm_series_method, ser); return(data); }
int main(int argc, char **argv) { FILE *fp; SERIES *ser; double *x, *y; unsigned i, j, sz; unsigned vdx[XSZ - 1] = { 1, 2, 4, 8, 16 }; unsigned vdy[YSZ - 1] = { 3, 6 }; ser = series_create(); for(i = 0; i < SZ; i++) series_append_val(ser, i); ser->x_width = XSZ; ser->y_width = YSZ; ser->x_delta = 2; ser->y_delta = 1; ser->step = 1; ser->offset = 2; series_reinitiate(ser); fp = fopen("tseries-xy.out", "w"); sz = series_get_num_pat(ser); for(i = 0; i < sz; i++) { x = series_get_x_pat(ser, i); for(j = 0; j < XSZ; j++) fprintf(fp, j < (XSZ - 1) ? "%d\t" : "%d\t\t", (int)x[j]); y = series_get_y_pat(ser, i); for(j = 0; j < YSZ; j++) fprintf(fp, j < (YSZ - 1) ? "%d\t" : "%d\n", (int)y[j]); } fclose(fp); ser->var_x_deltas = vdx; ser->var_y_deltas = NULL; series_reinitiate(ser); fp = fopen("tseries-Xy.out", "w"); sz = series_get_num_pat(ser); for(i = 0; i < sz; i++) { x = series_get_x_pat(ser, i); for(j = 0; j < XSZ; j++) fprintf(fp, j < (XSZ - 1) ? "%d\t" : "%d\t\t", (int)x[j]); y = series_get_y_pat(ser, i); for(j = 0; j < YSZ; j++) fprintf(fp, j < (YSZ - 1) ? "%d\t" : "%d\n", (int)y[j]); } fclose(fp); ser->var_x_deltas = NULL; ser->var_y_deltas = vdy; series_reinitiate(ser); fp = fopen("tseries-xY.out", "w"); sz = series_get_num_pat(ser); for(i = 0; i < sz; i++) { x = series_get_x_pat(ser, i); for(j = 0; j < XSZ; j++) fprintf(fp, j < (XSZ - 1) ? "%d\t" : "%d\t\t", (int)x[j]); y = series_get_y_pat(ser, i); for(j = 0; j < YSZ; j++) fprintf(fp, j < (YSZ - 1) ? "%d\t" : "%d\n", (int)y[j]); } fclose(fp); ser->var_x_deltas = vdx; ser->var_y_deltas = vdy; series_reinitiate(ser); fp = fopen("tseries-XY.out", "w"); sz = series_get_num_pat(ser); for(i = 0; i < sz; i++) { x = series_get_x_pat(ser, i); for(j = 0; j < XSZ; j++) fprintf(fp, j < (XSZ - 1) ? "%d\t" : "%d\t\t", (int)x[j]); y = series_get_y_pat(ser, i); for(j = 0; j < YSZ; j++) fprintf(fp, j < (YSZ - 1) ? "%d\t" : "%d\n", (int)y[j]); } fclose(fp); exit(0); }
fextract_series_t *pulses_calc(pitch_t *p, int nframes, mx_real_t *signal, int nsamples){ int i, x=0; mx_real_t globalPeak=signal[0]; mx_real_t t = 0; mx_real_t peak; double addedRight = -1e300; fextract_series_t *pulses = series_create(MAX_SERIES); for (i=1;i<nsamples;i++) { mx_real_t this = fabs(signal[i]); if (this > globalPeak) globalPeak=this; } /* * Cycle over all voiced intervals. */ for (;;) { mx_real_t tleft, tright, tmiddle, f0middle, tmax, tsave; x++; if (! getVoicedInterval (p, nframes, t, & tleft, & tright)) break; /* * Go to the middle of the voice stretch. */ tmiddle = (tleft + tright) / 2; f0middle = getPitchValueAt(p,nframes,tmiddle); /* * Our first point is near this middle. */ tmax = findExtremum (signal, nsamples, tmiddle - 0.5 / f0middle, tmiddle + 0.5 / f0middle); series_add(pulses,tmax); //find pulses backward tsave = tmax; for (;;) { mx_real_t f0 , correlation, last_tmax; f0 = getPitchValueAt(p,nframes,tmax); if (f0==-1) break; last_tmax=tmax; correlation = findMaximumCorrelation (signal, nsamples, tmax, 1.0 / f0, tmax - 1.25 / f0, tmax - 0.8 / f0, & tmax, & peak); if (correlation == -1 || tmax >last_tmax) /*break*/ tmax -= 1.0 / f0; /* This one period will drop out. */ if (tmax < tleft) { if (correlation > 0.7 && peak > 0.023333 * globalPeak && tmax - addedRight > 0.8 / f0) { series_add(pulses,tmax); } break; } if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { if (tmax - addedRight > 0.8 / f0) { /* Do not fill in a short originally unvoiced interval twice. */ series_add(pulses,tmax); } } } //find pulses forward tmax = tsave; for (;;) { mx_real_t f0 , correlation, last_tmax; f0 = getPitchValueAt(p,nframes,tmax); if (f0==-1) break; last_tmax=tmax; correlation = findMaximumCorrelation (signal, nsamples, tmax, 1.0 / f0, tmax + 0.8 / f0, tmax + 1.25 / f0, & tmax, & peak); if (correlation == -1 || tmax <last_tmax) /*break*/ tmax += 1.0 / f0; if (tmax > tright) { if (correlation > 0.7 && peak > 0.023333 * globalPeak) { series_add(pulses,tmax); addedRight = tmax; } break; } if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { series_add(pulses,tmax); addedRight = tmax; } } t = tright; } qsort(pulses->series,pulses->nSeries,sizeof(mx_real_t),_cmp_mx_real); return pulses; }
int _fextract_calc(fextract_t *fex, mx_real_t *features, dsp_sample_t *signal, char *pfile) { mx_real_t *pitch=NULL, *hnr=NULL; mx_real_t **_mfcc_series, **_energy_series; mx_real_t overall_max=0, overall_max_ind=0; int nframes=0, i, j, n_voiced_frames, max; int last_max=0, last_min=0, ser=0, max_sum=0, en_mean=0, fcount=0; fextract_series_t * serie=NULL; if (fex->frame_len==0) { rs_warning("Cannot compute features for segment of size 0!"); return -1; } fex->n_features=V1_N_FEATURES; _mfcc_series= (mx_real_t **) rs_malloc(MFCC_FEATURES * sizeof(mx_real_t *), "mfcc feature series"); for (i=0;i<MFCC_FEATURES;i++) _mfcc_series[i]= (mx_real_t *) rs_malloc(MAX_FRAMES * sizeof(mx_real_t), "mfcc features"); _energy_series= (mx_real_t **) rs_malloc(ENERGY_FEATURES * sizeof(mx_real_t *), "energy feature series"); for (i=0;i<3;i++) _energy_series[i]= (mx_real_t *) rs_malloc(MAX_FRAMES * sizeof(mx_real_t), "energy features"); if (pfile) { FILE *pfile_fp= fopen(pfile,"r"); if (!pfile_fp) rs_warning("pitch file %s not found!",pfile); /* read external pitch values */ pitch = (mx_real_t *) rs_malloc(MAX_FRAMES * sizeof(mx_real_t),"external pitch values"); j=MAX_FRAMES; i=0; while (fscanf(pfile_fp,"%g",&pitch[i])==1) { if (j == i+1) { j+=MAX_FRAMES; pitch = (mx_real_t *) rs_realloc(pitch,j*sizeof(mx_real_t),"external pitch values"); } i++; } nframes=i; fclose(pfile_fp); } else { pitch= pitch_calc (fex->pitch,signal,fex->frame_len); nframes=fex->pitch->nframes; } if (!pitch) { for (;fcount<STATS*9+7;fcount++) features[fcount]=-1.0; n_voiced_frames=-1.0; } else { const int series_size=9; // @begin_change_johannes //fextract_series_t *serien[series_size]; fextract_series_t *serien[9]; // @end_change_johannes // printRawXML(pitch,nframes,"pitch"); pitch_frame_candidates_destroy(fex->pitch); for (i=0;i<series_size;i++) serien[i]=series_create(MAX_SERIES); if (pitch[0]!=0) series_add(serien[0],pitch[0]); for (i=1;i<nframes-1;i++) { if (pitch[i]!=0) series_add(serien[0],pitch[i]); if (pitch[i-1]<pitch[i] && pitch[i]>pitch[i+1]) { series_add(serien[1],pitch[i]); if (pitch[i] > overall_max) { overall_max=pitch[i]; overall_max_ind=i; } series_add(serien[2],i-last_min); series_add(serien[3],pitch[i]-pitch[last_min]); series_add(serien[4],(pitch[i]-pitch[last_min])/(i-last_min)); last_max=i; } else if (pitch[i-1]>pitch[i] && pitch[i]<pitch[i+1]) { series_add(serien[5],pitch[i]); series_add(serien[6],i-last_max); series_add(serien[7],pitch[i]-pitch[last_max]); series_add(serien[8],(pitch[i]-pitch[last_max])/(i-last_max)); last_min=i; } } overall_max_ind = 1.0 * (overall_max_ind+1) / nframes; if (nframes >1 && pitch[nframes-1]!=0) series_add(serien[0],pitch[nframes-1]); for (i=0; i<series_size; i++) { getStatistics(features+fcount,serien[i]->series,serien[i]->nSeries); //pitch statistics features fcount+=STATS; } // normierter Mittelwert, normierter Median, normiertes 1. Quartil, normiertes 3. Quartil if (features[1]-features[2]) { features[fcount++]=(features[0]-features[2])/(features[1]-features[2]); features[fcount++]=(features[5]-features[2])/(features[1]-features[2]); features[fcount++]=(features[6]-features[2])/(features[1]-features[2]); features[fcount++]=(features[7]-features[2])/(features[1]-features[2]); } else { features[fcount++]=0; features[fcount++]=0; features[fcount++]=0; features[fcount++]=0; } features[fcount++]=1.0 * serien[1]->nSeries/nframes; // Anzahl Maxima pro Frames pro Segment features[fcount++]=1.0 * serien[5]->nSeries/nframes; // Anzahl Minima pro Frames pro Segment features[fcount++]=overall_max_ind; // Position des Maximums n_voiced_frames=serien[0]->nSeries; for (i=0;i<series_size;i++) series_destroy(serien[i]); } getEnergy_and_MFCC(fex->mfcc, signal, fex->frame_len, &_energy_series, &_mfcc_series, &ser); // ser=0; if (ser) { const int series_size = 8; // @begin_change_johannes //fextract_series_t *serien[series_size]; fextract_series_t *serien[8]; // @end_change_johannes for (i=0;i<series_size;i++) serien[i]=series_create(MAX_SERIES); fcount+=getMFCCFeatures(features+fcount, _mfcc_series,ser); /* Energie-Merkmale: */ last_max=last_min=0; for (i=1;i<ser-1;i++) { if (_energy_series[0][i-1]<_energy_series[0][i] && _energy_series[0][i]>_energy_series[0][i+1]) { series_add(serien[0], _energy_series[0][i]); //Maxima max_sum += _energy_series[0][i]; series_add(serien[1], i-last_min); // Laenge der Maxima series_add(serien[2], _energy_series[0][i]-_energy_series[0][last_min]); // Groesse der Maxima series_add(serien[3], (_energy_series[0][i]-_energy_series[0][last_min])/(i-last_min)); // Steigung der Maxima last_max=i; } else if (_energy_series[0][i-1]>_energy_series[0][i] && _energy_series[0][i]<_energy_series[0][i+1]) { series_add(serien[4], _energy_series[0][i]); //Maxima series_add(serien[5], i-last_max); // Laenge der Maxima series_add(serien[6], _energy_series[0][i]-_energy_series[0][last_max]); // Groesse der Maxima series_add(serien[7], (_energy_series[0][i]-_energy_series[0][last_min])/(i-last_max)); // Steigung der Maxima last_max=i; } } getStatistics(features+fcount,_energy_series[0],ser); // energy statistics en_mean=features[fcount+1]; fcount+=STATS; for (i=0;i<series_size;i++) { getStatistics(features+fcount,serien[i]->series,serien[i]->nSeries); fcount+=STATS; } max=serien[0]->nSeries; for (j=1;j<3;j++) { series_reset(serien[0]); series_reset(serien[1]); for (i=1;i<ser-1;i++) { if (_energy_series[j][i-1]<_energy_series[j][i] && _energy_series[j][i]>_energy_series[j][i+1]) { series_add(serien[0], _energy_series[j][i]); } else if (_energy_series[j][i-1]>_energy_series[j][i] && _energy_series[j][i]<_energy_series[j][i+1]) { series_add(serien[1], _energy_series[j][i]); } } getStatistics(features+fcount,_energy_series[j],ser); // energy delta statistics fcount+=STATS; getStatistics(features+fcount,serien[0]->series,serien[0]->nSeries); fcount+=STATS; getStatistics(features+fcount,serien[1]->series,serien[1]->nSeries); fcount+=STATS; } features[fcount++]= max? (1.0 * max_sum/max) - en_mean:0; // Mittelwert der Maxima minus globaler Mittelwert features[fcount++]= (1.0 * max)/ser; // Anzahl Maxima pro Frames pro Segment for (i=0;i<series_size;i++) series_destroy(serien[i]); } else { for (;fcount < 141*STATS+9;fcount++) features[fcount]=-1; } /* Voiced/Unvoiced-Merkmal: */ features[fcount++]=nframes ? (1.0 * n_voiced_frames)/nframes : -1; // Anzahl stimmloser Frames pro Frames pro Segment /* Spectral Center of gravity-Merkmale: */ serie = getOnlyCoG(signal,fex->frame_len); if (serie) { getStatistics(features+fcount,serie->series,serie->nSeries); series_destroy(serie); fcount+=STATS; } else for (;fcount< 142*STATS+10;fcount++) features[fcount]=-1; /* Dauer-Merkmal: */ features[fcount++]=fex->frame_len; /* Harmonics-to-Noise-Ratio-Merkmale: */ hnr=hnr_calc(fex->hnr,signal,fex->frame_len); nframes=fex->hnr->nframes; if (!hnr) for (;fcount<145*STATS+11;fcount++) features[fcount]=-1.0; else { const int series_size=3; // @begin_change_johannes //fextract_series_t *serien[series_size]; fextract_series_t *serien[3]; // @end_change_johannes pitch_frame_candidates_destroy(fex->hnr); for (i=0;i<series_size;i++) serien[i]=series_create(MAX_SERIES); if (hnr[0]!=0) series_add(serien[0],hnr[0]); for (i=1;i<nframes-1;i++) { if (hnr[i]!=-200) { series_add(serien[0],hnr[i]); if ((hnr[i-1]!=-200) && (hnr[i+1]!=200)) { // stimmlose Bereiche nicht beruecksichtigen if (hnr[i-1]<hnr[i] && hnr[i]>hnr[i+1]) series_add(serien[1],hnr[i]); else if (hnr[i-1]>hnr[i] && hnr[i]<hnr[i+1]) series_add(serien[2],hnr[i]); } } } if (nframes >1 && hnr[nframes-1]!=0) series_add(serien[0],hnr[nframes-1]); for (i=0; i<series_size; i++) { getStatistics(features+fcount,serien[i]->series,serien[i]->nSeries); //hnr statistics features fcount+=STATS; } } /* Aufraeumen... */ for (i=0;i<MFCC_FEATURES;i++) if (_mfcc_series[i]) rs_free(_mfcc_series[i]); if (_mfcc_series) rs_free(_mfcc_series); for (i=0;i<ENERGY_FEATURES;i++) if (_energy_series[i]) rs_free(_energy_series[i]); if (_energy_series) rs_free(_energy_series); if (pitch) rs_free(pitch); if (hnr) rs_free(hnr); /* for (;fcount<V1_N_FEATURES;fcount++) */ /* features[fcount]=0.0; */ if (fcount != V1_N_FEATURES) rs_error("number of features is not correct (%d expected, %d calculated)!",V1_N_FEATURES,fcount); return V1_N_FEATURES; }