int sc_main (int, char *[]) { sc_clock clock; sc_signal<bool> reset; sc_signal<bool> input_valid; sc_signal<int> sample; sc_signal<bool> output_data_ready; sc_signal<int> result; stimulus stimulus1("stimulus_block"); stimulus1.reset(reset); stimulus1.input_valid(input_valid); stimulus1.sample(sample); stimulus1.CLK(clock); fir fir1( "process_body"); fir1.reset(reset); fir1.input_valid(input_valid); fir1.sample(sample); fir1.output_data_ready(output_data_ready); fir1.result(result); fir1.CLK(clock); display display1 ( "display"); display1.output_data_ready(output_data_ready); display1.result(result); sc_start(); return 0; }
FP_TYPE* llsm_synthesize(llsm_parameters param, llsm* model, int* ny) { int nfrm = model -> conf.nfrm; int nhop = model -> conf.nhop; int fs = param.s_fs; int nfft = nhop * 4; *ny = nfrm * nhop + nfft; FP_TYPE* y_sin = calloc(*ny, sizeof(FP_TYPE)); FP_TYPE* y_env = calloc(*ny, sizeof(FP_TYPE)); FP_TYPE* y_env_mix = calloc(*ny, sizeof(FP_TYPE)); // D1 FP_TYPE** sin_phse = (FP_TYPE**)copy2d(model -> sinu -> phse, nfrm, model -> conf.nhar , sizeof(FP_TYPE)); FP_TYPE** env_phse = (FP_TYPE**)copy2d(model -> eenv -> phse, nfrm, model -> conf.nhare, sizeof(FP_TYPE)); FP_TYPE phse0 = 0; for(int i = 1; i < nfrm; i ++) { FP_TYPE f0 = model -> sinu -> freq[i][0]; phse0 += f0 * nhop / fs * 2.0 * M_PI; sin_phse[i][0] = fmod(phse0, 2.0 * M_PI) - M_PI; for(int j = 1; j < model -> conf.nhar; j ++) sin_phse[i][j] = sin_phse[i][0] / f0 * model -> sinu -> freq[i][j] + model -> sinu -> phse[i][j]; for(int j = 0; j < model -> conf.nhare; j ++) env_phse[i][j] = sin_phse[i][0] / f0 * model -> eenv -> freq[i][j] + model -> eenv -> phse[i][j]; } // D2, D3 FP_TYPE* ola_window = hanning(nhop * 2); for(int i = 0; i < nfrm; i ++) { int tn = i * nhop; if(model -> f0[i] <= 0.0) continue; FP_TYPE* sin_frame = synth_sinusoid_frame( model -> sinu -> freq[i], model -> sinu -> ampl[i], sin_phse[i], model -> conf.nhar, fs, nhop * 2); FP_TYPE* env_frame = synth_sinusoid_frame( model -> eenv -> freq[i], model -> eenv -> ampl[i], env_phse[i], model -> conf.nhare, fs, nhop * 2); for(int j = 0; j < nhop * 2; j ++) if(tn + j - nhop > 0) { y_sin[tn + j - nhop] += sin_frame[j] * ola_window[j]; y_env[tn + j - nhop] += env_frame[j] * ola_window[j]; } free(sin_frame); free(env_frame); } free2d(sin_phse, nfrm); free2d(env_phse, nfrm); // DA1 FP_TYPE* y_nos = synth_noise(param, model -> conf, model -> noise, 1); // DA2 const int filtord = 60; FP_TYPE* h_high = fir1(filtord, model -> conf.mvf / fs * 2.0, "highpass", "hanning"); FP_TYPE* h_low = fir1(filtord, model -> conf.mvf / fs * 2.0, "lowpass" , "hanning"); FP_TYPE* y_high = conv(y_nos, h_high, *ny, filtord); FP_TYPE* y_low = conv(y_nos, h_low , *ny, filtord); free(h_high); free(h_low); // DA3, D4 subtract_minimum_envelope(y_env, *ny, model -> f0, nhop, nfrm, fs); FP_TYPE* y_high_normalized = calloc(*ny, sizeof(FP_TYPE)); for(int i = 0; i < nfrm; i ++) { FP_TYPE* hfrm = fetch_frame(y_high + filtord / 2, *ny, i * nhop, nhop * 2); FP_TYPE* efrm = fetch_frame(y_env, *ny, i * nhop, nhop * 2); FP_TYPE havg = 0; for(int j = 0; j < nhop * 2; j ++) havg += hfrm[j] * hfrm[j]; havg /= nhop * 2; for(int j = 0; j < nhop * 2; j ++) hfrm[j] *= sqrt(1.0 / (havg + EPS)); if(model -> f0[i] <= 0.0) for(int j = 0; j < nhop * 2; j ++) efrm[j] = havg; else for(int j = 0; j < nhop * 2; j ++) efrm[j] += model -> emin[i]; for(int j = 0; j < nhop * 2; j ++) if(i * nhop + j - nhop > 0) { y_high_normalized[i * nhop + j - nhop] += hfrm[j] * ola_window[j]; y_env_mix [i * nhop + j - nhop] += efrm[j] * ola_window[j]; } free(hfrm); free(efrm); } free(ola_window); free(y_high); // DB1, DB2 for(int i = 0; i < *ny - nfft; i ++) y_sin[i] += y_low[i + filtord / 2] + y_high_normalized[i] * sqrt(fabs(y_env_mix[i])); free(y_env_mix); free(y_high_normalized); free(y_nos); free(y_low); free(y_env); return y_sin; }
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; }