3 #ifndef SPECTMORPH_IFFT_SYNTH_HH
4 #define SPECTMORPH_IFFT_SYNTH_HH
11 namespace SpectMorph {
13 struct IFFTSynthTable;
22 double freq256_factor;
30 SIN_TABLE_SIZE = 4096,
34 static std::vector<float> sin_table;
37 enum WindowType { WIN_BLACKMAN_HARRIS_92, WIN_HANNING };
38 enum OutputMode { REPLACE, ADD };
40 IFFTSynth (
size_t block_size,
double mix_freq, WindowType win_type);
46 zero_float_block (block_size, fft_in);
55 inline void render_partial (
double freq,
double mag,
double phase);
56 void get_samples (
float *samples, OutputMode output_mode = REPLACE);
57 void precompute_tables();
59 double quantized_freq (
double freq);
64 std::vector<float> win_trans;
70 IFFTSynth::render_partial (
double mf_freq,
double mag,
double phase)
74 const int freq256 = sm_round_positive (mf_freq * freq256_factor);
75 const int ibin = freq256 >> 8;
76 float *sp = fft_in + 2 * (ibin - range);
77 const float *wmag_p = &table->win_trans[(freq256 & 0xff) * (range * 2 + 1)];
79 const float nmag = mag * mag_norm;
84 int iarg = sm_round_positive (phase * (SIN_TABLE_SIZE / (2 * M_PI)));
88 int iphase_adjust = freq256 * SIN_TABLE_SIZE / 512 + (SIN_TABLE_SIZE - SIN_TABLE_SIZE / 4);
89 iarg += iphase_adjust;
91 const float phase_rsmag = sin_table [iarg & SIN_TABLE_MASK] * nmag;
92 iarg += SIN_TABLE_SIZE / 4;
93 const float phase_rcmag = sin_table [iarg & SIN_TABLE_MASK] * nmag;
96 if (ibin > range && 2 * (ibin + range) <
static_cast<int> (block_size))
98 for (
int i = 0; i <= 2 * range; i++)
100 const float wmag = wmag_p[i];
101 *sp++ += phase_rcmag * wmag;
102 *sp++ += phase_rsmag * wmag;
108 for (
int i = -range; i <= range; i++)
110 const float wmag = wmag_p[i];
113 fft_in[-(ibin + i) * 2] += phase_rcmag * wmag;
114 fft_in[-(ibin + i) * 2 + 1] -= phase_rsmag * wmag;
116 else if ((ibin + i) == 0)
118 fft_in[0] += 2 * phase_rcmag * wmag;
120 else if (2 * (ibin + i) ==
static_cast<int> (block_size))
122 fft_in[1] += 2 * phase_rcmag * wmag;
124 else if (2 * (ibin + i) >
static_cast<int> (block_size))
126 int p = block_size - (2 * (ibin + i) - block_size);
128 fft_in[p] += phase_rcmag * wmag;
129 fft_in[p + 1] -= phase_rsmag * wmag;
133 fft_in[(ibin + i) * 2] += phase_rcmag * wmag;
134 fft_in[(ibin + i) * 2 + 1] += phase_rsmag * wmag;
Definition: smifftsynth.hh:16
Definition: smifftsynth.hh:63