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