int main() { double m, stddev; int hist[n_bins], samples = 10; while (samples <= 10000) { m = avg(samples, &stddev, hist); printf("size %5d: %g %g\n", samples, m, stddev); samples *= 10; } printf("\nHistograph:\n"); hist_plot(hist); printf("\nMoving average:\n N Mean Sigma\n"); moving_rec rec = { 0, 0, 0, {0} }; double data[100]; for (int i = 0; i < 10000; i++) { for (int j = 0; j < 100; j++) data[j] = rand01(); moving_avg(&rec, data, 100); if ((i % 1000) == 999) { printf("%4lluk %f %f\n", rec.size/1000, rec.sum / rec.size, sqrt(rec.x2 * rec.size - rec.sum * rec.sum)/rec.size ); } } }
llsm* llsm_analyze(llsm_parameters param, FP_TYPE* x, int nx, int fs, FP_TYPE* f0, int nf0) { llsm* model = malloc(sizeof(llsm)); model -> sinu = malloc(sizeof(llsm_sinparam)); model -> eenv = malloc(sizeof(llsm_sinparam)); int nfft = pow(2, ceil(log2(fs * param.a_tfft))); FP_TYPE fftbuff[65536]; // C2 FP_TYPE** spectrogram = (FP_TYPE**)malloc2d(nf0, nfft / 2, sizeof(FP_TYPE)); FP_TYPE** phasegram = (FP_TYPE**)malloc2d(nf0, nfft / 2, sizeof(FP_TYPE)); FP_TYPE** phasegram_d = (FP_TYPE**)malloc2d(nf0, nfft / 2, sizeof(FP_TYPE)); spectrogram_analyze(param, x, nx, fs, f0, nf0, nfft, fftbuff, "blackman_harris", spectrogram, phasegram, phasegram_d, NULL); // C3 model -> f0 = refine_f0(param, nfft, fs, f0, nf0, spectrogram, phasegram, phasegram_d); FP_TYPE* rf0 = f0; // C4 model -> sinu -> freq = (FP_TYPE**)malloc2d(nf0, param.a_nhar, sizeof(FP_TYPE)); model -> sinu -> ampl = (FP_TYPE**)malloc2d(nf0, param.a_nhar, sizeof(FP_TYPE)); model -> sinu -> phse = (FP_TYPE**)malloc2d(nf0, param.a_nhar, sizeof(FP_TYPE)); FP_TYPE* tmpfreq = calloc(nf0, sizeof(FP_TYPE)); FP_TYPE* tmpampl = calloc(nf0, sizeof(FP_TYPE)); FP_TYPE* tmpphse = calloc(nf0, sizeof(FP_TYPE)); for(int i = 0; i < param.a_nhar; i ++) { find_harmonic_trajectory(param, spectrogram, phasegram, nfft, fs, rf0, nf0, i + 1, tmpfreq, tmpampl, tmpphse); for(int j = 0; j < nf0; j ++) { model -> sinu -> freq[j][i] = tmpfreq[j]; model -> sinu -> ampl[j][i] = tmpampl[j]; model -> sinu -> phse[j][i] = tmpphse[j]; } if(i == 0) for(int j = 0; j < nf0; j ++) if(fabs(rf0[j] - tmpfreq[j]) > 1) rf0[j] = tmpfreq[j]; } free2d(spectrogram, nf0); free2d(phasegram, nf0); free2d(phasegram_d, nf0); // C6 FP_TYPE* resynth = calloc(nx + param.a_nhop, sizeof(FP_TYPE)); int nresynth = 2 * param.a_nhop; FP_TYPE* resynth_window = hanning(nresynth); for(int i = 0; i < nf0; i ++) { int tn = i * param.a_nhop; FP_TYPE* resynth_frame = synth_sinusoid_frame( model -> sinu -> freq[i], model -> sinu -> ampl[i], model -> sinu -> phse[i], param.a_nhar, fs, nresynth); for(int j = 0; j < nresynth; j ++) if(tn + j - nresynth / 2 > 0) resynth[tn + j - nresynth / 2] += resynth_frame[j] * resynth_window[j]; free(resynth_frame); } free(resynth_window); // C7 -> CB7 for(int i = 0; i < nx; i ++) resynth[i] = x[i] - resynth[i]; FP_TYPE** noise_spectrogram = (FP_TYPE**)malloc2d(nf0, nfft / 2, sizeof(FP_TYPE)); model -> noise = (FP_TYPE**)calloc(nf0, sizeof(FP_TYPE*)); spectrogram_analyze(param, resynth, nx, fs, f0, nf0, nfft, fftbuff, "hanning", noise_spectrogram, NULL, NULL, NULL); free(resynth); FP_TYPE* freqwrap = llsm_wrap_freq(0, fs / 2, param.a_nnos, param.a_noswrap); for(int t = 0; t < nf0; t ++) { /* // cut out the spectrum content around harmonics FP_TYPE resf = f0[t]; int winlen = min(nfft, floor(fs / resf * 2.5) * 2); int wmlobe = ceil(1.3 * nfft / winlen); for(int i = 0; i < param.a_nhar; i ++) { FP_TYPE centerf = model -> sinu -> freq[t][i]; if(centerf > fs / nfft) { // make sure the frequency is valid int lbin = max(0 , round(centerf / fs * nfft - wmlobe)); int hbin = min(nfft / 2 - 1, round(centerf / fs * nfft + wmlobe)); for(int j = lbin; j <= hbin; j ++) noise_spectrogram[t][j] = -30; } }*/ model -> noise[t] = llsm_geometric_envelope(noise_spectrogram[t], nfft / 2, fs, freqwrap, param.a_nnos); } free(freqwrap); free2d(noise_spectrogram, nf0); // CB2 const int filtord = 60; FP_TYPE* h = fir1(filtord, param.a_mvf / fs * 2.0, "highpass", "hanning"); FP_TYPE* xh = conv(x, h, nx, filtord); free(h); // CB3 for(int i = 0; i < nx + filtord - 1; i ++) xh[i] = xh[i] * xh[i]; int mavgord = round(fs / param.a_mvf * 5); FP_TYPE* xhe = moving_avg(xh + filtord / 2, nx, mavgord); free(xh); // CB5 FP_TYPE** env_spectrogram = (FP_TYPE**)malloc2d(nf0, nfft / 2, sizeof(FP_TYPE)); FP_TYPE** env_phasegram = (FP_TYPE**)malloc2d(nf0, nfft / 2, sizeof(FP_TYPE)); model -> emin = calloc(nf0, sizeof(FP_TYPE)); spectrogram_analyze(param, xhe + mavgord / 2, nx, fs, f0, nf0, nfft, fftbuff, "blackman_harris", env_spectrogram, env_phasegram, NULL, model -> emin); free(xhe); // CB6 model -> eenv -> freq = (FP_TYPE**)malloc2d(nf0, param.a_nhar, sizeof(FP_TYPE)); model -> eenv -> ampl = (FP_TYPE**)malloc2d(nf0, param.a_nhar, sizeof(FP_TYPE)); model -> eenv -> phse = (FP_TYPE**)malloc2d(nf0, param.a_nhar, sizeof(FP_TYPE)); for(int i = 0; i < param.a_nhare; i ++) { find_harmonic_trajectory(param, env_spectrogram, env_phasegram, nfft, fs, rf0, nf0, i + 1, tmpfreq, tmpampl, tmpphse); for(int j = 0; j < nf0; j ++) { model -> eenv -> freq[j][i] = tmpfreq[j]; model -> eenv -> ampl[j][i] = tmpampl[j]; model -> eenv -> phse[j][i] = tmpphse[j]; } } free(tmpfreq); free(tmpampl); free(tmpphse); free2d(env_spectrogram, nf0); free2d(env_phasegram, nf0); // CB8 for(int i = 0; i < nf0; i ++) { FP_TYPE base = model -> sinu -> phse[i][0]; if(rf0[i] <= 0.0) continue; for(int j = 0; j < param.a_nhar; j ++) { model -> sinu -> phse[i][j] -= base * model -> sinu -> freq[i][j] / rf0[i]; model -> sinu -> phse[i][j] = fmod(model -> sinu -> phse[i][j], M_PI * 2.0); } for(int j = 0; j < param.a_nhare; j ++) { model -> eenv -> phse[i][j] -= base * model -> eenv -> freq[i][j] / rf0[i]; model -> eenv -> phse[i][j] = fmod(model -> eenv -> phse[i][j], M_PI * 2.0); } } model -> sinu -> nfrm = nf0; model -> eenv -> nfrm = nf0; model -> sinu -> nhar = param.a_nhar; model -> eenv -> nhar = param.a_nhare; model -> conf.nfrm = nf0; model -> conf.nhop = param.a_nhop; model -> conf.nhar = param.a_nhar; model -> conf.nhare = param.a_nhare; model -> conf.nnos = param.a_nnos; model -> conf.nosf = fs / 2.0; model -> conf.mvf = param.a_mvf; model -> conf.noswrap = param.a_noswrap; return model; }