void CheapTrick(const double *x, int x_length, int fs, const double *temporal_positions, const double *f0, int f0_length, const CheapTrickOption *option, double **spectrogram) { int fft_size = option->fft_size; randn_reseed(); double f0_floor = GetF0FloorForCheapTrick(fs, fft_size); double *spectral_envelope = new double[fft_size]; ForwardRealFFT forward_real_fft = {0}; InitializeForwardRealFFT(fft_size, &forward_real_fft); InverseRealFFT inverse_real_fft = {0}; InitializeInverseRealFFT(fft_size, &inverse_real_fft); double current_f0; for (int i = 0; i < f0_length; ++i) { current_f0 = f0[i] <= f0_floor ? world::kDefaultF0 : f0[i]; CheapTrickGeneralBody(x, x_length, fs, current_f0, fft_size, temporal_positions[i], option->q1, &forward_real_fft, &inverse_real_fft, spectral_envelope); for (int j = 0; j <= fft_size / 2; ++j) spectrogram[i][j] = spectral_envelope[j]; } DestroyForwardRealFFT(&forward_real_fft); DestroyInverseRealFFT(&inverse_real_fft); delete[] spectral_envelope; }
void CheapTrick(double *x, int x_length, int fs, double *time_axis, double *f0, int f0_length, double **spectrogram) { int fft_size = GetFFTSizeForCheapTrick(fs); double *spectral_envelope = new double[fft_size]; ForwardRealFFT forward_real_fft = {0}; InitializeForwardRealFFT(fft_size, &forward_real_fft); InverseRealFFT inverse_real_fft = {0}; InitializeInverseRealFFT(fft_size, &inverse_real_fft); double current_f0; for (int i = 0; i < f0_length; ++i) { current_f0 = f0[i] <= world::kFloorF0 ? world::kDefaultF0 : f0[i]; CheapTrickGeneralBody(x, x_length, fs, current_f0, fft_size, time_axis[i], &forward_real_fft, &inverse_real_fft, spectral_envelope); for (int j = 0; j <= fft_size / 2; ++j) spectrogram[i][j] = spectral_envelope[j]; } DestroyForwardRealFFT(&forward_real_fft); DestroyInverseRealFFT(&inverse_real_fft); delete[] spectral_envelope; }
void Synthesis(const double *f0, int f0_length, const double *const*spectrogram, const double *const*residual_spectrogram, int fft_size, double frame_period, int fs, int y_length, double *y) { double *impulse_response = new double[fft_size]; MinimumPhaseAnalysis minimum_phase = {0}; InitializeMinimumPhaseAnalysis(fft_size, &minimum_phase); InverseRealFFT inverse_real_fft = {0}; InitializeInverseRealFFT(fft_size, &inverse_real_fft); double current_time = 0.0; int current_position = 0; int current_frame = 0; // Length used for the synthesis is unclear. const int kFrameLength = 3 * fft_size / 4; while (1) { GetOneFrameSegment(f0, spectrogram, residual_spectrogram, fft_size, current_frame, &minimum_phase, &inverse_real_fft, impulse_response); for (int i = current_position; i < MyMin(current_position + kFrameLength, y_length - 1); ++i) y[i] += impulse_response[i - current_position]; // update current_time += 1.0 / (f0[current_frame] == 0.0 ? world::kDefaultF0 : f0[current_frame]); current_frame = matlab_round(current_time / (frame_period / 1000.0)); current_position = static_cast<int>(current_time * fs); if (current_frame >= f0_length) break; } DestroyMinimumPhaseAnalysis(&minimum_phase); DestroyInverseRealFFT(&inverse_real_fft); delete[] impulse_response; }