void model_addorreplacedata(model* m, char tag[], int vid, int alloctype, void* data) { modeldata* mdata; int i; int ni, nj, nk; for (i = 0; i < m->ndata; ++i) if (strcmp(tag, m->data[i].tag) == 0) break; mdata = &m->data[i]; if (i == m->ndata) { if (m->ndata % NMODELDATA_INC == 0) m->data = realloc(m->data, (m->ndata + NMODELDATA_INC) * sizeof(modeldata)); mdata->tag = strdup(tag); mdata->vid = vid; mdata->alloctype = alloctype; m->ndata++; } else assert(mdata->alloctype == alloctype); model_getvardims(m, mdata->vid, &ni, &nj, &nk); if (mdata->alloctype == ALLOCTYPE_1D) memcpy(mdata->data, data, nk * sizeof(float)); else if (mdata->alloctype == ALLOCTYPE_2D) mdata->data = copy2d(data, nj, ni, sizeof(float)); else if (mdata->alloctype == ALLOCTYPE_3D) mdata->data = copy3d(data, nk, nj, ni, sizeof(float)); else enkf_quit("programming error"); }
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; }