| 82 | |
| 83 | template <class InputSample, class OutputSample> |
| 84 | bool Spectrogram::ComputeComplexSpectrogram( |
| 85 | const std::vector<InputSample>& input, |
| 86 | std::vector<std::vector<complex<OutputSample>>>* output) { |
| 87 | if (!initialized_) { |
| 88 | LOG(ERROR) << "ComputeComplexSpectrogram() called before successful call " |
| 89 | << "to Initialize()."; |
| 90 | return false; |
| 91 | } |
| 92 | CHECK(output); |
| 93 | output->clear(); |
| 94 | int input_start = 0; |
| 95 | while (GetNextWindowOfSamples(input, &input_start)) { |
| 96 | DCHECK_EQ(input_queue_.size(), window_length_); |
| 97 | ProcessCoreFFT(); // Processes input_queue_ to fft_input_output_. |
| 98 | // Add a new slice vector onto the output, to save new result to. |
| 99 | output->resize(output->size() + 1); |
| 100 | // Get a reference to the newly added slice to fill in. |
| 101 | auto& spectrogram_slice = output->back(); |
| 102 | spectrogram_slice.resize(output_frequency_channels_); |
| 103 | for (int i = 0; i < output_frequency_channels_; ++i) { |
| 104 | // This will convert double to float if it needs to. |
| 105 | spectrogram_slice[i] = complex<OutputSample>( |
| 106 | fft_input_output_[2 * i], fft_input_output_[2 * i + 1]); |
| 107 | } |
| 108 | } |
| 109 | return true; |
| 110 | } |
| 111 | // Instantiate it four ways: |
| 112 | template bool Spectrogram::ComputeComplexSpectrogram( |
| 113 | const std::vector<float>& input, std::vector<std::vector<complex<float>>>*); |