| 132 | } |
| 133 | |
| 134 | void SpectrumStack::calc_fft() |
| 135 | { |
| 136 | _spectrum_state = Running; |
| 137 | // Get the dso data |
| 138 | pv::data::DsoSnapshot *data = NULL; |
| 139 | pv::view::DsoSignal *dsoSig = NULL; |
| 140 | |
| 141 | for(auto s : _session->get_signals()) { |
| 142 | if (s->signal_type() == SR_CHANNEL_DSO) { |
| 143 | dsoSig = (view::DsoSignal*)s; |
| 144 | if (dsoSig->get_index() == _index && dsoSig->enabled()) { |
| 145 | data = dsoSig->data(); |
| 146 | break; |
| 147 | } |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | if (data == NULL || data->empty()) |
| 152 | return; |
| 153 | |
| 154 | if (data->get_sample_count() < _sample_num * _sample_interval) |
| 155 | return; |
| 156 | |
| 157 | // Get the samplerate |
| 158 | _samplerate = data->samplerate(); |
| 159 | if (_samplerate == 0.0) |
| 160 | _samplerate = 1.0; |
| 161 | |
| 162 | // prepare _xn data |
| 163 | const int offset = dsoSig->get_hw_offset(); |
| 164 | const double vscale = dsoSig->get_vDialValue() * dsoSig->get_factor() * DS_CONF_DSO_VDIVS / (1000*255.0); |
| 165 | const uint16_t step = _sample_interval; |
| 166 | const uint8_t *const samples = data->get_samples(0, _sample_num*_sample_interval-1, _index); |
| 167 | double wsum = 0; |
| 168 | |
| 169 | for (unsigned int i = 0; i < _sample_num; i++) { |
| 170 | double w = window(i, _windows_index); |
| 171 | _xn[i] = (samples[i*step] - offset) * vscale * w; |
| 172 | wsum += w; |
| 173 | } |
| 174 | |
| 175 | // fft |
| 176 | fftw_execute(_fft_plan); |
| 177 | |
| 178 | // calculate power spectrum |
| 179 | _power_spectrum[0] = abs(_xk[0])/wsum; /* DC component */ |
| 180 | for (unsigned int k = 1; k < (_sample_num + 1) / 2; ++k) /* (k < N/2 rounded up) */ |
| 181 | _power_spectrum[k] = sqrt((_xk[k]*_xk[k] + _xk[_sample_num-k]*_xk[_sample_num-k]) * 2) / wsum; |
| 182 | if (_sample_num % 2 == 0) /* N is even */ |
| 183 | _power_spectrum[_sample_num/2] = abs(_xk[_sample_num/2])/wsum; /* Nyquist freq. */ |
| 184 | |
| 185 | _spectrum_state = Stopped; |
| 186 | } |
| 187 | |
| 188 | double SpectrumStack::window(uint64_t i, int type) |
| 189 | { |
no test coverage detected