// Process samples. void PhaseDiscriminator::process(const IQSampleVector& samples_in, SampleVector& samples_out) { unsigned int n = samples_in.size(); IQSample s0 = m_last1_sample; samples_out.resize(n); for (unsigned int i = 0; i < n; i++) { IQSample s1(samples_in[i]); IQSample d(conj(s0) * s1); //Sample w = atan2(d.imag(), d.real()); Sample w = fastatan2(d.imag(), d.real()); // fast approximation of atan2 samples_out[i] = w * m_freq_scale_factor; s0 = s1; } m_last2_sample = m_last1_sample; m_last1_sample = s0; }
static FP_TYPE* synth_noise(llsm_parameters param, llsm_conf conf, FP_TYPE** wrapped_spectrogram, int winsize) { /* To suppress glitches caused by aliasing, we apply MLT sine window twice, before analysis and after synthesis respectively; Overlapping factor should be greater or equal to 4 for MLT sine window; To preserve time resolution, we actually lower the hopsize by half, meanwhile double sampling wrapped_spectrogram. */ conf.nhop /= 2; int nfft = winsize * conf.nhop * 2; int ny = conf.nfrm * conf.nhop * 2 + nfft * 16; FP_TYPE* y = calloc(ny, sizeof(FP_TYPE)); FP_TYPE* w = hanning(nfft); FP_TYPE* realbuff = calloc(nfft, sizeof(FP_TYPE)); FP_TYPE* imagbuff = calloc(nfft, sizeof(FP_TYPE)); FP_TYPE* yfrm = calloc(nfft, sizeof(FP_TYPE)); FP_TYPE fftbuff[65536]; FP_TYPE norm_factor = 0.5 * sumfp(w, nfft); FP_TYPE norm_factor_win = 0; { int i = 0; while(i < nfft) { norm_factor_win += w[i]; i += conf.nhop; } } for(int j = 0; j < nfft; j ++) w[j] = sqrt(w[j]); FP_TYPE* x = white_noise(1.0, ny); FP_TYPE* freqwrap = llsm_wrap_freq(0, conf.nosf, conf.nnos, conf.noswrap); for(int i = 0; i < conf.nfrm * 2; i ++) { int t = i * conf.nhop; FP_TYPE* spec = llsm_spectrum_from_envelope(freqwrap, wrapped_spectrogram[i / 2], conf.nnos, nfft / 2, param.s_fs); FP_TYPE* xfrm = fetch_frame(x, ny, t, nfft); for(int j = 0; j < nfft; j ++) xfrm[j] *= w[j]; fft(xfrm, NULL, realbuff, imagbuff, nfft, fftbuff); for(int j = 0; j < nfft / 2; j ++) { FP_TYPE a = fastexp(spec[j]) * norm_factor; // amplitude FP_TYPE p = fastatan2(imagbuff[j], realbuff[j]); realbuff[j] = a * cos(p); imagbuff[j] = a * sin(p); } complete_symm (realbuff, nfft); complete_asymm(imagbuff, nfft); ifft(realbuff, imagbuff, yfrm, NULL, nfft, fftbuff); for(int j = 0; j < nfft; j ++) { int idx = t + j - nfft / 2; if(idx >= 0) y[idx] += yfrm[j] * w[j] / norm_factor_win; } free(spec); free(xfrm); } free(w); free(x); free(yfrm); free(realbuff); free(imagbuff); free(freqwrap); return y; }