OpenShot Library | libopenshot  0.2.6
STFT.cpp
Go to the documentation of this file.
1 #include "STFT.h"
2 
3 using namespace openshot;
4 
5 void STFT::setup(const int num_input_channels)
6 {
7  num_channels = (num_input_channels > 0) ? num_input_channels : 1;
8 }
9 
10 void STFT::updateParameters(const int new_fft_size, const int new_overlap, const int new_window_type)
11 {
12  updateFftSize(new_fft_size);
13  updateHopSize(new_overlap);
14  updateWindow(new_window_type);
15 }
16 
17 void STFT::process(juce::AudioSampleBuffer &block)
18 {
19  num_samples = block.getNumSamples();
20 
21  for (int channel = 0; channel < num_channels; ++channel) {
22  float *channel_data = block.getWritePointer(channel);
23 
28 
29  for (int sample = 0; sample < num_samples; ++sample) {
30  const float input_sample = channel_data[sample];
31 
32  input_buffer.setSample(channel, current_input_buffer_write_position, input_sample);
35  // diff
36  channel_data[sample] = output_buffer.getSample(channel, current_output_buffer_read_position);
37 
38  output_buffer.setSample(channel, current_output_buffer_read_position, 0.0f);
41 
44  analysis(channel);
45  modification(channel);
46  synthesis(channel);
47  }
48  }
49  }
50 
55 }
56 
57 
58 void STFT::updateFftSize(const int new_fft_size)
59 {
60  if (new_fft_size != fft_size)
61  {
62  fft_size = new_fft_size;
63  fft = std::make_unique<juce::dsp::FFT>(log2(fft_size));
64 
66  input_buffer.clear();
67  input_buffer.setSize(num_channels, input_buffer_length);
68 
70  output_buffer.clear();
72 
73  fft_window.realloc(fft_size);
74  fft_window.clear(fft_size);
75 
78 
81 
86  }
87 }
88 
89 void STFT::updateHopSize(const int new_overlap)
90 {
91  if (new_overlap != overlap)
92  {
93  overlap = new_overlap;
94 
95  if (overlap != 0) {
98  }
99  }
100 }
101 
102 
103 void STFT::updateWindow(const int new_window_type)
104 {
105  window_type = new_window_type;
106 
107  switch (window_type) {
108  case RECTANGULAR: {
109  for (int sample = 0; sample < fft_size; ++sample)
110  fft_window[sample] = 1.0f;
111  break;
112  }
113  case BART_LETT: {
114  for (int sample = 0; sample < fft_size; ++sample)
115  fft_window[sample] = 1.0f - fabs (2.0f * (float)sample / (float)(fft_size - 1) - 1.0f);
116  break;
117  }
118  case HANN: {
119  for (int sample = 0; sample < fft_size; ++sample)
120  fft_window[sample] = 0.5f - 0.5f * cosf (2.0f * M_PI * (float)sample / (float)(fft_size - 1));
121  break;
122  }
123  case HAMMING: {
124  for (int sample = 0; sample < fft_size; ++sample)
125  fft_window[sample] = 0.54f - 0.46f * cosf (2.0f * M_PI * (float)sample / (float)(fft_size - 1));
126  break;
127  }
128  }
129 
130  float window_sum = 0.0f;
131  for (int sample = 0; sample < fft_size; ++sample)
132  window_sum += fft_window[sample];
133 
134  window_scale_factor = 0.0f;
135  if (overlap != 0 && window_sum != 0.0f)
136  window_scale_factor = 1.0f / (float)overlap / window_sum * (float)fft_size;
137 }
138 
139 
140 
141 void STFT::analysis(const int channel)
142 {
143  int input_buffer_index = current_input_buffer_write_position;
144  for (int index = 0; index < fft_size; ++index) {
145  time_domain_buffer[index].real(fft_window[index] * input_buffer.getSample(channel, input_buffer_index));
146  time_domain_buffer[index].imag(0.0f);
147 
148  if (++input_buffer_index >= input_buffer_length)
149  input_buffer_index = 0;
150  }
151 }
152 
153 void STFT::modification(const int channel)
154 {
156 
157  for (int index = 0; index < fft_size / 2 + 1; ++index) {
158  float magnitude = abs(frequency_domain_buffer[index]);
159  float phase = arg(frequency_domain_buffer[index]);
160 
161  frequency_domain_buffer[index].real(magnitude * cosf (phase));
162  frequency_domain_buffer[index].imag(magnitude * sinf (phase));
163 
164  if (index > 0 && index < fft_size / 2) {
165  frequency_domain_buffer[fft_size - index].real(magnitude * cosf (phase));
166  frequency_domain_buffer[fft_size - index].imag(magnitude * sinf (-phase));
167  }
168  }
169 
171 }
172 
173 void STFT::synthesis(const int channel)
174 {
175  int output_buffer_index = current_output_buffer_write_position;
176  for (int index = 0; index < fft_size; ++index) {
177  float output_sample = output_buffer.getSample(channel, output_buffer_index);
178  output_sample += time_domain_buffer[index].real() * window_scale_factor;
179  output_buffer.setSample(channel, output_buffer_index, output_sample);
180 
181  if (++output_buffer_index >= output_buffer_length)
182  output_buffer_index = 0;
183  }
184 
188 }
virtual void updateHopSize(const int new_overlap)
Definition: STFT.cpp:89
int hop_size
Definition: STFT.h:58
float window_scale_factor
Definition: STFT.h:60
void updateParameters(const int new_fft_size, const int new_overlap, const int new_window_type)
Definition: STFT.cpp:10
juce::HeapBlock< juce::dsp::Complex< float > > time_domain_buffer
Definition: STFT.h:54
int output_buffer_length
Definition: STFT.h:50
int input_buffer_write_position
Definition: STFT.h:62
int num_channels
Definition: STFT.h:41
juce::HeapBlock< float > fft_window
Definition: STFT.h:53
void setup(const int num_input_channels)
Definition: STFT.cpp:5
int output_buffer_read_position
Definition: STFT.h:64
int output_buffer_write_position
Definition: STFT.h:63
void process(juce::AudioSampleBuffer &block)
Definition: STFT.cpp:17
juce::AudioSampleBuffer input_buffer
Definition: STFT.h:48
juce::AudioSampleBuffer output_buffer
Definition: STFT.h:51
int overlap
Definition: STFT.h:57
int window_type
Definition: STFT.h:59
int current_samples_since_last_FFT
Definition: STFT.h:70
int current_output_buffer_write_position
Definition: STFT.h:68
int num_samples
Definition: STFT.h:42
int current_input_buffer_write_position
Definition: STFT.h:67
std::unique_ptr< juce::dsp::FFT > fft
Definition: STFT.h:45
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:46
virtual void updateFftSize(const int new_fft_size)
Definition: STFT.cpp:58
juce::HeapBlock< juce::dsp::Complex< float > > frequency_domain_buffer
Definition: STFT.h:55
int input_buffer_length
Definition: STFT.h:47
int current_output_buffer_read_position
Definition: STFT.h:69
int fft_size
Definition: STFT.h:44
int samples_since_last_FFT
Definition: STFT.h:65
virtual void updateWindow(const int new_window_type)
Definition: STFT.cpp:103