OpenShot Library | libopenshot 0.2.7
STFT.cpp
Go to the documentation of this file.
1#include "STFT.h"
2
3using namespace openshot;
4
5void STFT::setup(const int num_input_channels)
6{
7 num_channels = (num_input_channels > 0) ? num_input_channels : 1;
8}
9
10void 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
17void 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
58void 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();
68
70 output_buffer.clear();
72
73 fft_window.realloc(fft_size);
74 fft_window.clear(fft_size);
75
78
81
86 }
87}
88
89void 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
103void 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
141void 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
153void 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
173void 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}
int input_buffer_length
Definition: STFT.h:47
int output_buffer_read_position
Definition: STFT.h:64
int input_buffer_write_position
Definition: STFT.h:62
int output_buffer_length
Definition: STFT.h:50
int hop_size
Definition: STFT.h:58
int num_samples
Definition: STFT.h:42
int num_channels
Definition: STFT.h:41
void process(juce::AudioSampleBuffer &block)
Definition: STFT.cpp:17
juce::AudioSampleBuffer output_buffer
Definition: STFT.h:51
virtual void updateWindow(const int new_window_type)
Definition: STFT.cpp:103
int current_input_buffer_write_position
Definition: STFT.h:67
juce::HeapBlock< juce::dsp::Complex< float > > frequency_domain_buffer
Definition: STFT.h:55
std::unique_ptr< juce::dsp::FFT > fft
Definition: STFT.h:45
void updateParameters(const int new_fft_size, const int new_overlap, const int new_window_type)
Definition: STFT.cpp:10
int output_buffer_write_position
Definition: STFT.h:63
juce::HeapBlock< float > fft_window
Definition: STFT.h:53
virtual void updateHopSize(const int new_overlap)
Definition: STFT.cpp:89
int current_output_buffer_read_position
Definition: STFT.h:69
juce::AudioSampleBuffer input_buffer
Definition: STFT.h:48
int fft_size
Definition: STFT.h:44
float window_scale_factor
Definition: STFT.h:60
int overlap
Definition: STFT.h:57
int current_samples_since_last_FFT
Definition: STFT.h:70
juce::HeapBlock< juce::dsp::Complex< float > > time_domain_buffer
Definition: STFT.h:54
int window_type
Definition: STFT.h:59
virtual void updateFftSize(const int new_fft_size)
Definition: STFT.cpp:58
int samples_since_last_FFT
Definition: STFT.h:65
int current_output_buffer_write_position
Definition: STFT.h:68
This namespace is the default namespace for all code in the openshot library.
Definition: Compressor.h:47
@ RECTANGULAR
Definition: Enums.h:130
@ HANN
Definition: Enums.h:132
@ BART_LETT
Definition: Enums.h:131
@ HAMMING
Definition: Enums.h:133