vec spectrum(const vec &v, int nfft, int noverlap) { it_assert_debug(pow2i(levels2bits(nfft)) == nfft, "nfft must be a power of two in spectrum()!"); vec P(nfft / 2 + 1), w(nfft), wd(nfft); P = 0.0; w = hanning(nfft); double w_energy = nfft == 1 ? 1 : (nfft + 1) * .375; // Hanning energy if (nfft > v.size()) { P = sqr(abs(fft(to_cvec(elem_mult(zero_pad(v, nfft), w)))(0, nfft / 2))); P /= w_energy; } else { int k = (v.size() - noverlap) / (nfft - noverlap), idx = 0; for (int i = 0; i < k; i++) { wd = elem_mult(v(idx, idx + nfft - 1), w); P += sqr(abs(fft(to_cvec(wd))(0, nfft / 2))); idx += nfft - noverlap; } P /= k * w_energy; } P.set_size(nfft / 2 + 1, true); return P; }
equalizer::equalizer(int bands, const int hnSize, const int HwSize) : size_(bands),hnSize_(hnSize),HwSize_(HwSize),verbose_(false),wnd_(0) { bands_ = new float[size_]; freqs_ = new float[size_]; for (int i=0;i<size_;++i) { bands_[i]=1.0; freqs_[i]=0.0; } // initialize FFT transformers // Buffer that holds the frequency domain data Hw_ = reinterpret_cast<fftwf_complex*> (fftwf_malloc(sizeof(fftwf_complex)*HwSize_)); memset(Hw_,0,HwSize_*sizeof(fftwf_complex)); // Even if the size of h(n) is hnSize_, we use HwSize because zero // padding is to be performed hn_ = reinterpret_cast<float*>(fftwf_malloc(sizeof(float)*HwSize_)); memset(hn_,0,sizeof(float)*HwSize_); ifft_ = fftwf_plan_dft_c2r_1d(HwSize_,Hw_,hn_,FFTW_MEASURE); fft_ = fftwf_plan_dft_r2c_1d(HwSize_,hn_,Hw_,FFTW_MEASURE); hanning(); //rectangular(); }
Periodogram* newPeriodogram(int nFFT, int windowsize) { Periodogram* newperiodogram = (Periodogram*)malloc(sizeof(Periodogram)); newperiodogram->nFFT = nFFT; newperiodogram->real = (float*)calloc(nFFT,sizeof(float)); newperiodogram->imaginary = (float*)calloc(nFFT,sizeof(float)); newperiodogram->sine = (float*)malloc((nFFT/2)*sizeof(float)); newperiodogram->cosine = (float*)malloc((nFFT/2)*sizeof(float)); newperiodogram->windowing = (float*)malloc(windowsize*sizeof(float)); hanning(newperiodogram->windowing,windowsize); // Hanning window precomputing //precompute twiddle factors for fft float arg; int i; for (i=0;i<nFFT/2;i++) { arg = -2*3.14159265358979*i/nFFT; newperiodogram->cosine[i] = cos(arg); newperiodogram->sine[i] = sin(arg); } return newperiodogram; }
/* prepare window for FFT * INPUT * n : # of samples for FFT * flag_window : 0 : no-window (default -- that is, other than 1 ~ 6) * 1 : parzen window * 2 : welch window * 3 : hanning window * 4 : hamming window * 5 : blackman window * 6 : steeper 30-dB/octave rolloff window * OUTPUT * density factor as RETURN VALUE */ double init_den (int n, char flag_window) { double den; int i; den = 0.0; for (i = 0; i < n; i ++) { switch (flag_window) { case 1: // parzen window den += parzen (i, n) * parzen (i, n); break; case 2: // welch window den += welch (i, n) * welch (i, n); break; case 3: // hanning window den += hanning (i, n) * hanning (i, n); break; case 4: // hamming window den += hamming (i, n) * hamming (i, n); break; case 5: // blackman window den += blackman (i, n) * blackman (i, n); break; case 6: // steeper 30-dB/octave rolloff window den += steeper (i, n) * steeper (i, n); break; default: fprintf (stderr, "invalid flag_window\n"); case 0: // square (no window) den += 1.0; break; } } den *= (double)n; return den; }
double Denoise::fft_window(int k, int N, int window_type) { if(window_type == DENOISE_WINDOW_BLACKMAN) { return blackman(k, N); } else if(window_type == DENOISE_WINDOW_BLACKMAN_HYBRID) { return blackman_hybrid(k, N-N/4, N); } else if(window_type == DENOISE_WINDOW_HANNING_OVERLAP_ADD) { return hanning(k, N); } return 0.0; }
int compute_itegral_r(const mu_data_fit *mu, const fit_params fp, gsl_vector *fftR_abs){ size_t vsize= mu->k->size; gsl_vector *mu_tmp=gsl_vector_alloc(vsize); gsl_vector_set_zero(mu_tmp); size_t ikmin=search_min(mu->k, mu->kmin - 0.5*mu->dwk); size_t ikmax=search_min(mu->k, mu->kmax + 0.5*mu->dwk); gsl_vector_view kw = gsl_vector_subvector(mu->k, ikmin-1, ikmax-ikmin-1); gsl_vector_view muw = gsl_vector_subvector(mu_tmp, ikmin-1, ikmax-ikmin-1); gsl_vector *ktmp=gsl_vector_alloc((&kw.vector)->size); gsl_vector_memcpy(ktmp, &kw.vector); gsl_vector_add_constant(ktmp, fp.kshift); compute_itegral(ktmp, &fp, &muw.vector); hanning(mu_tmp, mu->k, mu->kmin, mu->kmax, mu->dwk); //FFT transform double *data = (double *) malloc(vsize*sizeof(double)); memcpy(data, mu_tmp->data, vsize*sizeof(double)); gsl_fft_real_radix2_transform(data, 1, vsize); //Unpack complex vector gsl_vector_complex *fourier_data = gsl_vector_complex_alloc (vsize); gsl_fft_halfcomplex_radix2_unpack(data, fourier_data->data, 1, vsize); gsl_vector *fftR_real = gsl_vector_alloc(vsize/2); gsl_vector *fftR_imag = gsl_vector_alloc(vsize/2); //gsl_vector *fftR_abs = gsl_vector_alloc(vsize/2); complex_vector_parts(fourier_data, fftR_real, fftR_imag); complex_vector_abs(fftR_abs, fftR_real, fftR_imag); hanning(fftR_abs, mu->r, mu->rmin, mu->rmax, mu->dwr); gsl_vector_free(fftR_real); gsl_vector_free(fftR_imag); gsl_vector_complex_free(fourier_data); gsl_vector_free(mu_tmp); free(data); }
/* * Hanning window */ static VectorObject * py_hanning(PyObject *self, PyObject *args) { int N; VectorObject *out; if (!PyArg_ParseTuple(args, "i", &N) || N < 1) { PyErr_SetString(PyExc_ValueError, "argument must be a positive Integer"); return NULL; } out = vector_new(N); hanning(N, out->data); return out; }
static float peakerror(float *fpreal, float *fpimag, float pidetune, float norm, float peakreal, float peakimag) { float sinpidetune = sin(pidetune); float cospidetune = cos(pidetune); float windowshould = hanning(pidetune, sinpidetune); float realshould = windowshould * ( peakreal * cospidetune + peakimag * sinpidetune); float imagshould = windowshould * ( peakimag * cospidetune - peakreal * sinpidetune); float realgot = norm * (fpreal[0] - 0.5 * (fpreal[1] + fpreal[-1])); float imaggot = norm * (fpimag[0] - 0.5 * (fpimag[1] + fpimag[-1])); float realdev = realshould - realgot, imagdev = imagshould - imaggot; /* post("real %f->%f; imag %f->%f", realshould, realgot, imagshould, imaggot); */ return (realdev * realdev + imagdev * imagdev); }
//----------------------------------------------------------------------------- // name: init() // desc: ... //----------------------------------------------------------------------------- t_CKBOOL AudicleFaceVMSpace::init( ) { if( !AudicleFace::init() ) return FALSE; // set the buffer_size g_buffer_size = Digitalio::m_buffer_size; // set the channels g_num_channels = Digitalio::m_num_channels_out; // allocate buffers g_out_buffer = new SAMPLE[g_buffer_size*g_num_channels]; g_in_buffer = new SAMPLE[g_buffer_size*g_num_channels]; g_buffer = new SAMPLE[g_buffer_size*g_num_channels]; g_window = NULL; // set the buffer Digitalio::set_extern( g_in_buffer, g_out_buffer ); g_rect = new SAMPLE[g_buffer_size]; g_hamm = new SAMPLE[g_buffer_size]; g_hann = new SAMPLE[g_buffer_size]; // blackmann blackman( g_rect, g_buffer_size ); // hanning hanning( g_hann, g_buffer_size ); // hamming window hamming( g_hamm, g_buffer_size ); g_window = g_hamm; g_spectrums = new Pt2D *[g_depth]; for( int i = 0; i < g_depth; i++ ) { g_spectrums[i] = new Pt2D[g_buffer_size]; memset( g_spectrums[i], 0, sizeof(Pt2D)*g_buffer_size ); } g_draw = new GLboolean[g_depth]; memset( g_draw, 0, sizeof(GLboolean)*g_depth ); m_name = "VM-Space"; m_bg_speed = .2; g_id = IDManager::instance()->getPickID(); g_id2 = IDManager::instance()->getPickID(); return TRUE; }
/* apply window function to data[] * INPUT * flag_window : 0 : no-window (default -- that is, other than 1 ~ 6) * 1 : parzen window * 2 : welch window * 3 : hanning window * 4 : hamming window * 5 : blackman window * 6 : steeper 30-dB/octave rolloff window */ void windowing (int n, const double *data, int flag_window, double scale, double *out) { int i; for (i = 0; i < n; i ++) { switch (flag_window) { case 1: // parzen window out [i] = data [i] * parzen (i, n) / scale; break; case 2: // welch window out [i] = data [i] * welch (i, n) / scale; break; case 3: // hanning window out [i] = data [i] * hanning (i, n) / scale; break; case 4: // hamming window out [i] = data [i] * hamming (i, n) / scale; break; case 5: // blackman window out [i] = data [i] * blackman (i, n) / scale; break; case 6: // steeper 30-dB/octave rolloff window out [i] = data [i] * steeper (i, n) / scale; break; default: fprintf (stderr, "invalid flag_window\n"); case 0: // square (no window) out [i] = data [i] / scale; break; } } }
//----------------------------------------------------------------------------- // Name: initialize_audio( ) // Desc: set up audio capture and playback and initializes any application data //----------------------------------------------------------------------------- bool initialize_audio( ) { Stk::setSampleRate( g_srate ); try { // open the audio device for capture and playback g_audio = new RtAudio(); RtAudio::StreamParameters inputParameters; inputParameters.deviceId = g_audio->getDefaultInputDevice(); inputParameters.nChannels = g_sndin; RtAudio::StreamParameters outputParameters; outputParameters.deviceId = g_audio->getDefaultOutputDevice(); outputParameters.nChannels = g_sndout; g_audio->openStream( &outputParameters, &inputParameters, RTAUDIO_FLOAT32, g_srate, &g_buffer_size, cb, NULL); // do the pvc g_pvc = pv_create( g_window_size, /*1024*/ PVC_BUFFER_SIZE, 2048 ); pv_set_window( g_pvc, PV_HANNING ); // start the audio g_audio->startStream( ); // make the window hanning( g_window, g_buffer_size ); } catch( RtAudioError & e ) { // exception fprintf( stderr, "%s\n", e.getMessage().c_str() ); fprintf( stderr, "error: cannot open audio device for capture/playback...\n" ); return false; } return true; }
void Visualizer::Initialize() { CoInitializeEx(NULL, COINIT_MULTITHREADED); CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pMMDeviceEnumerator); pMMDeviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pMMDevice); pMMDevice->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pAudioClient); pAudioClient->GetMixFormat(&waveformat); pAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_LOOPBACK, 0, 0, waveformat, 0); pAudioClient->GetService(__uuidof(IAudioCaptureClient), (void**)&pAudioCaptureClient); pAudioClient->Start(); rkb.Initialize(); ckb.Initialize(); //str.Initialize(); amplitude = 100; avg_mode = 0; avg_size = 8; bkgd_step = 0; bkgd_bright = 10; bkgd_mode = 0; delay = 50; window_mode = 1; decay = 80; frgd_mode = 8; single_color_mode = 1; hanning(win_hanning, 256); hamming(win_hamming, 256); blackman(win_blackman, 256); nrml_ofst = 0.04f; nrml_scl = 0.5f; SetNormalization(nrml_ofst, nrml_scl); }
static void pique_doit(int npts, t_word *fpreal, t_word *fpimag, int npeak, int *nfound, t_float *fpfreq, t_float *fpamp, t_float *fpampre, t_float *fpampim, t_float errthresh) { t_float srate = sys_getsr(); /* not sure how to get this correctly */ t_float oneovern = 1.0/ (t_float)npts; t_float fperbin = srate * oneovern; t_float pow1, pow2 = 0, pow3 = 0, pow4 = 0, pow5 = 0; t_float re1, re2 = 0, re3 = fpreal->w_float; t_float im1, im2 = 0, im3 = 0, powthresh, relativeerror; int count, peakcount = 0, n2 = (npts >> 1); t_float *fp1, *fp2; t_word *wp1, *wp2; for (count = n2, wp1 = fpreal, wp2 = fpimag, powthresh = 0; count--; wp1++, wp2++) powthresh += (wp1->w_float) * (wp1->w_float) + (wp2->w_float) * (wp2->w_float) ; powthresh *= 0.00001; for (count = 1; count < n2; count++) { t_float windreal, windimag, pi = 3.14159; t_float detune, pidetune, sinpidetune, cospidetune, ampcorrect, freqout, ampout, ampoutreal, ampoutimag; t_float rpeak, rpeaknext, rpeakprev; t_float ipeak, ipeaknext, ipeakprev; t_float errleft, errright; fpreal++; fpimag++; re1 = re2; re2 = re3; re3 = fpreal->w_float; im1 = im2; im2 = im3; im3 = fpimag->w_float; if (count < 2) continue; pow1 = pow2; pow2 = pow3; pow3 = pow4; pow4 = pow5; /* get Hanning-windowed spectrum by convolution */ windreal = re2 - 0.5 * (re1 + re3); windimag = im2 - 0.5 * (im1 + im3); pow5 = windreal * windreal + windimag * windimag; /* if (count < 30) post("power %f", pow5); */ if (count < 5) continue; /* check for a peak. The actual bin is count-3. */ if (pow3 <= pow2 || pow3 <= pow4 || pow3 <= pow1 || pow3 <= pow5 || pow3 < powthresh) continue; /* go back for the raw FFT values around the peak. */ rpeak = fpreal[-3].w_float; rpeaknext = fpreal[-2].w_float; rpeakprev = fpreal[-4].w_float; ipeak = fpimag[-3].w_float; ipeaknext = fpimag[-2].w_float; ipeakprev = fpimag[-4].w_float; /* recalculate Hanning-windowed spectrum by convolution */ windreal = rpeak - 0.5 * (rpeaknext + rpeakprev); windimag = ipeak - 0.5 * (ipeaknext + ipeakprev); detune = ((rpeakprev - rpeaknext) * (2.0 * rpeak - rpeakprev - rpeaknext) + (ipeakprev - ipeaknext) * (2.0 * ipeak - ipeakprev - ipeaknext)) / (4.0 * pow3); /* if (count < 30) post("detune %f", detune); */ if (detune > 0.7 || detune < -0.7) continue; /* the frequency is the sum of the bin frequency and detuning */ freqout = fperbin * ((t_float)(count-3) + detune); pidetune = pi * detune; sinpidetune = sin(pidetune); cospidetune = cos(pidetune); ampcorrect = 1.0 / hanning(pidetune, sinpidetune); /* Multiply by 2 to get real-sinusoid peak amplitude and divide by N to normalize FFT */ ampcorrect *= 2. * oneovern; /* amplitude is peak height, corrected for Hanning window shape */ ampout = ampcorrect * sqrt(pow3); ampoutreal = ampcorrect * (windreal * cospidetune - windimag * sinpidetune); ampoutimag = ampcorrect * (windreal * sinpidetune + windimag * cospidetune); if (errthresh > 0) { /* post("peak %f %f", freqout, ampout); */ errleft = peakerror(fpreal-4, fpimag-4, pidetune+pi, 2. * oneovern, ampoutreal, ampoutimag); errright = peakerror(fpreal-2, fpimag-2, pidetune-pi, 2. * oneovern, ampoutreal, ampoutimag); relativeerror = (errleft + errright)/(ampout * ampout); if (relativeerror > errthresh) continue; } /* post("power %f, error %f, relative %f", pow3, errleft + errright, relativeerror); */ *fpfreq++ = freqout; *fpamp++ = ampout; *fpampre++ = ampoutreal; *fpampim++ = ampoutimag; if (++peakcount == npeak) break; } *nfound = peakcount; }
/* Design FIR filter using the Window method n filter length must be odd for HP and BS filters w buffer for the filter taps (must be n long) fc cutoff frequencies (1 for LP and HP, 2 for BP and BS) 0 < fc < 1 where 1 <=> Fs/2 flags window and filter type as defined in filter.h variables are ored together: i.e. LP|HAMMING will give a low pass filter designed using a hamming window opt beta constant used only when designing using kaiser windows returns 0 if OK, -1 if fail */ TfirFilter::_ftype_t* TfirFilter::design_fir(unsigned int *n, _ftype_t* fc, int type, int window, _ftype_t opt) { unsigned int o = *n & 1; // Indicator for odd filter length unsigned int end = ((*n + 1) >> 1) - o; // Loop end unsigned int i; // Loop index _ftype_t k1 = 2 * _ftype_t(M_PI); // 2*pi*fc1 _ftype_t k2 = 0.5f * (_ftype_t)(1 - o);// Constant used if the filter has even length _ftype_t k3; // 2*pi*fc2 Constant used in BP and BS design _ftype_t g = 0.0f; // Gain _ftype_t t1,t2,t3; // Temporary variables _ftype_t fc1,fc2; // Cutoff frequencies // Sanity check if(*n==0) return NULL; fc[0]=limit(fc[0],_ftype_t(0.001),_ftype_t(1)); if (!o && (type==TfirSettings::BANDSTOP || type==TfirSettings::HIGHPASS)) (*n)++; _ftype_t *w=(_ftype_t*)aligned_calloc(sizeof(_ftype_t),*n); // Get window coefficients switch(window){ case(TfirSettings::WINDOW_BOX): boxcar(*n,w); break; case(TfirSettings::WINDOW_TRIANGLE): triang(*n,w); break; case(TfirSettings::WINDOW_HAMMING): hamming(*n,w); break; case(TfirSettings::WINDOW_HANNING): hanning(*n,w); break; case(TfirSettings::WINDOW_BLACKMAN): blackman(*n,w); break; case(TfirSettings::WINDOW_FLATTOP): flattop(*n,w); break; case(TfirSettings::WINDOW_KAISER): kaiser(*n,w,opt); break; default: { delete []w; return NULL; } } if(type==TfirSettings::LOWPASS || type==TfirSettings::HIGHPASS){ fc1=*fc; // Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2 fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25f; k1 *= fc1; if(type==TfirSettings::LOWPASS){ // Low pass filter // If the filter length is odd, there is one point which is exactly // in the middle. The value at this point is 2*fCutoff*sin(x)/x, // where x is zero. To make sure nothing strange happens, we set this // value separately. if (o){ w[end] = fc1 * w[end] * 2.0f; g=w[end]; } // Create filter for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1) - k2; w[end-i-1] = w[*n-end+i] = _ftype_t(w[end-i-1] * sin(k1 * t1)/(M_PI * t1)); // Sinc g += 2*w[end-i-1]; // Total gain in filter } } else{ // High pass filter //if (!o) // High pass filters must have odd length // return -1; w[end] = _ftype_t(1.0 - (fc1 * w[end] * 2.0)); g= w[end]; // Create filter for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1); w[end-i-1] = w[*n-end+i] = _ftype_t(-1 * w[end-i-1] * sin(k1 * t1)/(M_PI * t1)); // Sinc g += ((i&1) ? (2*w[end-i-1]) : (-2*w[end-i-1])); // Total gain in filter } } } if(type==TfirSettings::BANDPASS || type==TfirSettings::BANDSTOP){ fc1=fc[0]; fc2=limit(fc[1],_ftype_t(0.001),_ftype_t(1)); // Cutoff frequencies must be < 1.0 where 1.0 <=> Fs/2 fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25f; fc2 = ((fc2 <= 1.0) && (fc2 > 0.0)) ? fc2/2 : 0.25f; k3 = k1 * fc2; // 2*pi*fc2 k1 *= fc1; // 2*pi*fc1 if(type==TfirSettings::BANDPASS){ // Band pass // Calculate center tap if (o){ g=w[end]*(fc1+fc2); w[end] = (fc2 - fc1) * w[end] * 2.0f; } // Create filter for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1) - k2; t2 = _ftype_t(sin(k3 * t1)/(M_PI * t1)); // Sinc fc2 t3 = _ftype_t(sin(k1 * t1)/(M_PI * t1)); // Sinc fc1 g += w[end-i-1] * (t3 + t2); // Total gain in filter w[end-i-1] = w[*n-end+i] = w[end-i-1] * (t2 - t3); } } else{ // Band stop //if (!o) // Band stop filters must have odd length // return -1; w[end] = _ftype_t(1.0 - (fc2 - fc1) * w[end] * 2.0); g= w[end]; // Create filter for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1); t2 = _ftype_t(sin(k1 * t1)/(M_PI * t1)); // Sinc fc1 t3 = _ftype_t(sin(k3 * t1)/(M_PI * t1)); // Sinc fc2 w[end-i-1] = w[*n-end+i] = w[end-i-1] * (t2 - t3); g += 2*w[end-i-1]; // Total gain in filter } } } // Normalize gain g=1/g; for (i=0; i<*n; i++) w[i] *= g; return w; }
//----------------------------------------------------------------------------- // name: fft_bandpass() // desc: bandpass filter the samples x - pass through frequencies between // bandStart * nyquist and bandEnd * nyquist unharmed, smoothly sloping down // the amplitudes of frequencies outside the passband to 0 over // rolloff * nyquist hz. //----------------------------------------------------------------------------- void fft_bandpass( Frame * x, float bandStart, float bandEnd, float rolloff ) { float *window = 0; int winsize = -1; int i; // not sure why we have at least 4 "pi" variables floating around // (#define PIE, #define PI, float PI earlier in this file, double pi local to functions) // got to combine them all some time. // double pi = 4.*atan(1.0); // make and apply hanning window if( winsize != x->wlen ){ winsize = x->wlen; if(window) delete[] window; window = new float[winsize]; hanning( window, winsize ); } apply_window( x->waveform, window, x->wlen ); // fft rfft( x->waveform, x->len, FFT_FORWARD ); BirdBrain::scale_fft( x->waveform, x->wlen, x->wlen, x->wsize ); x->cmp2pol(); // the core int rollWidth = (int)(rolloff * (float)x->len); int startIndex = (int)(bandStart * (float)x->len); int endIndex = (int)(bandEnd * (float)x->len); int lTail = startIndex - rollWidth; int rTail = endIndex + rollWidth; for(i = 0; i < lTail; i++){ x->pol[i].mag = 0; } for(i = lTail > 0 ? lTail : 0; i < startIndex; i++){ x->pol[i].mag *= 0.5 * (1 + cos(((float)(startIndex - i)) * PIE / (float)rollWidth)); } for(i = endIndex; (i < rTail) && (i < x->len); i++){ x->pol[i].mag *= 0.5 * (1 + cos(((float)(i - endIndex)) * PIE / (float)rollWidth)); } for(i = rTail; i < x->len; i++){ x->pol[i].mag = 0; } x->pol2cmp(); // inverse fft rfft( x->waveform, x->len, FFT_INVERSE); // inverse window! hanning( window, winsize ); for(i = 0; i < winsize; i++){ if(window[i] < 0.15) window[i] = 0.15f; window[i] = 1 / window[i]; } apply_window( x->waveform, window, x->wlen ); if( window ) delete[] window; }
int main(){ const int max_mu_size=601; const int zero_pad_size=pow(2,15); FILE *in; in= fopen("mean.chi", "r"); gsl_matrix *e = gsl_matrix_alloc(max_mu_size, 4); gsl_vector * kvar=gsl_vector_alloc(max_mu_size); gsl_vector * muvar=gsl_vector_alloc(max_mu_size); gsl_vector * mu_0pad=gsl_vector_alloc(zero_pad_size); gsl_vector * r_0pad=gsl_vector_alloc(zero_pad_size/2); //half of lenght gsl_vector * kvar_0pad=gsl_vector_alloc(zero_pad_size); gsl_matrix_fscanf(in, e); fclose(in); gsl_matrix_get_col(kvar,e,0); gsl_matrix_get_col(muvar,e,1); gsl_vector_set_zero(mu_0pad); gsl_matrix_free(e); double dk=gsl_vector_get (kvar, 1)-gsl_vector_get (kvar, 0); double dr=M_PI/float(zero_pad_size-1)/dk; for (int i = 0; i < zero_pad_size; i++) { gsl_vector_set (kvar_0pad, i, dk*i); } for (int i = 0; i < zero_pad_size/2; i++) { gsl_vector_set (r_0pad, i, dr*i); } for (int i = 0; i < max_mu_size; i++) { gsl_vector_set (mu_0pad, i, gsl_vector_get (muvar, i)); } gsl_vector *mu_widowed=gsl_vector_alloc(zero_pad_size); gsl_vector_memcpy (mu_widowed, mu_0pad); double kmin=4.0, kmax=17.0, dwk=0.8; hanning(mu_widowed, kvar_0pad, kmin, kmax, dwk); //FFT transform double *data = (double *) malloc(zero_pad_size*sizeof(double)); //new double [zero_pad_size] ; memcpy(data, mu_widowed->data, zero_pad_size*sizeof(double)); gsl_fft_real_radix2_transform(data, 1, zero_pad_size); //Unpack complex vector gsl_vector_complex *fourier_data = gsl_vector_complex_alloc (zero_pad_size); gsl_fft_halfcomplex_radix2_unpack(data, fourier_data->data, 1, zero_pad_size); gsl_vector *fftR_real = gsl_vector_alloc(fourier_data->size/2); gsl_vector *fftR_imag = gsl_vector_alloc(fourier_data->size/2); gsl_vector *fftR_abs = gsl_vector_alloc(fourier_data->size/2); complex_vector_parts(fourier_data, fftR_real, fftR_imag); complex_vector_abs(fftR_abs, fftR_real, fftR_imag); gsl_vector *first_shell=gsl_vector_alloc(fftR_abs->size); gsl_vector_memcpy (first_shell, fftR_abs); double rmin=0.2, rmax=3.0, dwr=0.1; hanning(first_shell, r_0pad, rmin, rmax, dwr); //feff0001.dat const int path_lines=68; e = gsl_matrix_alloc(path_lines, 7); gsl_vector * k_p =gsl_vector_alloc(path_lines); gsl_vector * phc_p=gsl_vector_alloc(path_lines); gsl_vector * mag_p=gsl_vector_alloc(path_lines); gsl_vector * pha_p=gsl_vector_alloc(path_lines); gsl_vector * lam_p=gsl_vector_alloc(path_lines); in= fopen("feff0001.dat", "r"); gsl_matrix_fscanf(in, e); fclose(in); gsl_matrix_get_col(k_p ,e,0); gsl_matrix_get_col(phc_p,e,1); gsl_matrix_get_col(mag_p,e,2); gsl_matrix_get_col(pha_p,e,3); gsl_matrix_get_col(lam_p,e,5); gsl_matrix_free(e); gsl_interp_accel *acc = gsl_interp_accel_alloc (); gsl_spline *k_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines); gsl_spline *phc_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines); gsl_spline *mag_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines); gsl_spline *pha_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines); gsl_spline *lam_spline = gsl_spline_alloc (gsl_interp_cspline, path_lines); gsl_spline_init (k_spline , k_p->data, k_p->data , path_lines); gsl_spline_init (phc_spline, k_p->data, phc_p->data, path_lines); gsl_spline_init (mag_spline, k_p->data, mag_p->data, path_lines); gsl_spline_init (pha_spline, k_p->data, pha_p->data, path_lines); gsl_spline_init (lam_spline, k_p->data, lam_p->data, path_lines); gsl_vector * mu_p =gsl_vector_alloc(path_lines); //struct fit_params { student_params t; double kshift; double S02; double N; inter_path splines; }; //student_params t = {2.45681867, 0.02776907, -21.28920008, 9.44741797, 0.0, 0.0, 0.0}; splines.acc=acc; splines.phc_spline=phc_spline; splines.mag_spline=mag_spline; splines.pha_spline=pha_spline; splines.lam_spline=lam_spline; fit_params fp = { 2.45681867, 0.02776907, -21.28920008, 9.44741797, 1.0, 0.0}; compute_itegral(k_p, &fp, mu_p); //mu_data_fit params = { k_p, mu_p}; mu_data.k = kvar_0pad; mu_data.mu = mu_0pad; mu_data.mu_ft = first_shell; mu_data.r = r_0pad; mu_data.kmin = kmin; mu_data.kmax = kmax; mu_data.rmin = rmin; mu_data.rmax = rmax; mu_data.dwk = dwk; mu_data.dwr = dwr; // initialize the solver size_t Nparams=6; gsl_vector *guess0 = gsl_vector_alloc(Nparams); gsl_vector_set(guess0, 0, 2.4307); gsl_vector_set(guess0, 1, 0.040969); gsl_vector_set(guess0, 2, 0.001314); gsl_vector_set(guess0, 3, 7835); gsl_vector_set(guess0, 4, 1.0); gsl_vector_set(guess0, 5, 0.0); gsl_vector *fit_r = gsl_vector_alloc(r_0pad->size); compute_itegral_r(&mu_data, fp, fit_r); gsl_matrix *plotting = gsl_matrix_calloc(r_0pad->size, 3); gsl_matrix_set_col (plotting, 0, r_0pad); gsl_matrix_set_col (plotting, 1, first_shell); gsl_matrix_set_col (plotting, 2, fit_r); plot_matplotlib(plotting); gsl_matrix_free (plotting); gsl_multifit_function_fdf fit_mu_k; fit_mu_k.f = &resudial_itegral_r; fit_mu_k.n = MAX_FIT_POINTS; fit_mu_k.p = Nparams; fit_mu_k.params = &mu_data; fit_mu_k.df = NULL; fit_mu_k.fdf = NULL; gsl_multifit_fdfsolver *solver = gsl_multifit_fdfsolver_alloc(gsl_multifit_fdfsolver_lmsder, MAX_FIT_POINTS, Nparams); gsl_multifit_fdfsolver_set(solver, &fit_mu_k, guess0); size_t iter=0, status; do{ iter++; //cout << solver->x->data[0] << " " << solver->x->data[1] <<endl; status = gsl_multifit_fdfsolver_iterate (solver); //printf("%12.4f %12.4f %12.4f\n", solver->J->data[0,0], solver->J->data[1,1], solver->J->data[2,2] ); //gsl_multifit_fdfsolver_dif_df (k_p, &fit_mu_k, mu_p, solver->J); //gsl_multifit_fdfsolver_dif_fdf (k_p, &fit_mu_k, mu_p, solver->J); for (int i =0; i< solver->x->size; i++){ printf("%14.5f", gsl_vector_get (solver->x, i)) ; } printf("\n") ; if (status) break; status = gsl_multifit_test_delta (solver->dx, solver->x, 1e-4, 1e-4); }while (status == GSL_CONTINUE && iter < 100); gsl_vector * mu_fit =gsl_vector_alloc(path_lines); fit_params fitp = { solver->x->data[0], solver->x->data[1],\ solver->x->data[2], solver->x->data[3],\ solver->x->data[4], solver->x->data[5]}; compute_itegral(k_p, &fitp, mu_fit); fp.mu=gsl_vector_get (solver->x, 0); fp.sig=gsl_vector_get (solver->x, 1); fp.skew=gsl_vector_get (solver->x, 2); fp.nu=gsl_vector_get (solver->x, 3); fp.S02=gsl_vector_get (solver->x, 4); fp.kshift=gsl_vector_get (solver->x, 5); compute_itegral_r(&mu_data, fp, fit_r); //gsl_matrix *plotting = gsl_matrix_calloc(r_0pad->size, 3); gsl_matrix_set_col (plotting, 0, r_0pad); gsl_matrix_set_col (plotting, 1, first_shell); gsl_matrix_set_col (plotting, 2, fit_r); int min_r=search_max(r_0pad, 0.); int max_r=search_max(r_0pad, 4.); gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_r, 0, max_r-min_r, plotting->size2); plot_matplotlib(&plotting_lim.matrix); gsl_matrix_free (plotting); //cout << gsl_spline_eval (k_spline, 1.333, acc) << endl; //cout << gsl_spline_eval (phc_spline, 1.333, acc) << endl; //cout << data[0] << "\t" << data[1] << "\t" << data[2] << "\t" << endl; //cout << fourier_data->data[0] << "\t" << fourier_data->data[1] << "\t" << fourier_data->data[2] << "\t" << endl; //Plotting /* gsl_matrix *plotting = gsl_matrix_calloc(zero_pad_size, 3); gsl_matrix_set_col (plotting, 0, kvar_0pad); gsl_matrix_set_col (plotting, 1, mu_0pad); gsl_matrix_set_col (plotting, 2, mu_widowed); int max_k=search_max(kvar_0pad, 35.); int min_k=search_max(kvar_0pad, 1.0); gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_k, 0, max_k-min_k, 3); plot_matplotlib(&plotting_lim.matrix); gsl_matrix_free (plotting); */ /* gsl_matrix *plotting = gsl_matrix_calloc(zero_pad_size, 2); gsl_matrix_set_col (plotting, 0, r_0pad); gsl_matrix_set_col (plotting, 1, mu_0pad); int max_k=search_max(kvar_0pad, 35.); int min_k=search_max(kvar_0pad, 1.0); gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_k, 0, max_k-min_k, 3); plot_matplotlib(&plotting_lim.matrix); gsl_matrix_free (plotting); */ /* gsl_matrix *plotting = gsl_matrix_calloc(r_0pad->size, 5); gsl_matrix_set_col (plotting, 0, r_0pad); gsl_matrix_set_col (plotting, 1, fftR_abs); gsl_matrix_set_col (plotting, 2, fftR_real); gsl_matrix_set_col (plotting, 3, fftR_imag); gsl_matrix_set_col (plotting, 4, first_shell); int min_r=search_max(r_0pad, 0.); int max_r=search_max(r_0pad, 5.); gsl_matrix_view plotting_lim = gsl_matrix_submatrix (plotting, min_r, 0, max_r-min_r, plotting->size2); plot_matplotlib(&plotting_lim.matrix); //plot_matplotlib(plotting); gsl_matrix_free (plotting); */ //cout << "Done" << endl; //cout << data[1] <<"\t" << data[2] << endl; //for (int i = 0; i < kvar->size; i++) //{ // cout << gsl_vector_get (kvar, i) <<"\t" << gsl_vector_get (muvar, i) << endl; //} }
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; }
static void spectrogram_analyze(llsm_parameters param, FP_TYPE* x, int nx, int fs, FP_TYPE* f0, int nf0, int nfft, FP_TYPE* fftbuff, const char* wtype, FP_TYPE** spectrogram, FP_TYPE** phasegram, FP_TYPE** phasegram_d, FP_TYPE* minvec) { FP_TYPE* xbuff = calloc(nfft, sizeof(FP_TYPE)); FP_TYPE* ybuffr = calloc(nfft, sizeof(FP_TYPE)); FP_TYPE* ybuffi = calloc(nfft, sizeof(FP_TYPE)); for(int t = 0; t < nf0; t ++) { // 4 times fundamental period is the minimal window length that resolves the harmonics // for generalized Hamming/Blackman windows FP_TYPE resf = f0[t]; int winlen = resf > 0 ? min(nfft, floor(fs / resf * 2.0) * 2) : param.a_nhop * 2; int tn = t * param.a_nhop; FP_TYPE* w = NULL; if(! strcmp(wtype, "blackman_harris")) w = blackman_harris(winlen); else if(! strcmp(wtype, "hamming")) w = hamming(winlen); else if(! strcmp(wtype, "hanning")) w = hanning(winlen); FP_TYPE norm_factor = 2.0 / sumfp(w, winlen); FP_TYPE* xfrm, * xfrm_d; FP_TYPE* spec_magn, * spec_phse_, * spec_phse, * spec_phse_d; xfrm = xfrm_d = spec_magn = spec_phse_ = spec_phse = spec_phse_d = NULL; xfrm = fetch_frame(x, nx, tn, winlen); FP_TYPE mean_xfrm = sumfp(xfrm, winlen) / winlen; if(minvec != NULL) minvec[t] = minfp(xfrm, winlen); for(int i = 0; i < winlen; i ++) xfrm[i] -= mean_xfrm; if(phasegram_d) { xfrm_d = fetch_frame(x, nx, tn - 1, winlen); FP_TYPE mean_xfrm_d = sumfp(xfrm_d, winlen) / winlen; for(int i = 0; i < winlen; i ++) xfrm_d[i] -= mean_xfrm_d; } for(int i = 0; i < winlen; i ++) { xfrm[i] *= w[i]; if(phasegram_d) xfrm_d[i] *= w[i]; } // current frame memset(xbuff, 0, nfft * sizeof(FP_TYPE)); for(int i = 0; i < winlen / 2; i ++) { xbuff[i] = xfrm[i + winlen / 2]; xbuff[nfft - winlen / 2 + i] = xfrm[i]; } fft(xbuff, NULL, ybuffr, ybuffi, nfft, fftbuff); spec_magn = abscplx(ybuffr, ybuffi, nfft / 2); if(phasegram) spec_phse_ = argcplx(ybuffr, ybuffi, nfft / 2); if(phasegram) spec_phse = unwrap(spec_phse_, nfft / 2); free(spec_phse_); // delayed frame if(phasegram_d) { memset(xbuff, 0, nfft * sizeof(FP_TYPE)); for(int i = 0; i < winlen / 2; i ++) { xbuff[i] = xfrm_d[i + winlen / 2]; xbuff[nfft - winlen / 2 + i] = xfrm_d[i]; } fft(xbuff, NULL, ybuffr, ybuffi, nfft, fftbuff); spec_phse_ = argcplx(ybuffr, ybuffi, nfft / 2); spec_phse_d = unwrap(spec_phse_, nfft / 2); free(spec_phse_); } for(int i = 0; i < nfft / 2; i ++) { spectrogram[t][i] = log(spec_magn[i] * norm_factor); if(isnan(spectrogram[t][i]) || isinf(spectrogram[t][i])) spectrogram[t][i] = -100.0; if(phasegram) phasegram[t][i] = spec_phse[i]; if(phasegram_d) phasegram_d[t][i] = spec_phse_d[i]; } free(spec_magn); if(spec_phse) free(spec_phse); if(spec_phse_d) free(spec_phse_d); free(xfrm); if(xfrm_d) free(xfrm_d); free(w); } free(xbuff); free(ybuffr); free(ybuffi); }
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; }
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; }