Skip to content

Commit

Permalink
Fixed weird noises in the audio robotization effect
Browse files Browse the repository at this point in the history
  • Loading branch information
BrennoCaldato committed Jul 10, 2021
1 parent 22b7408 commit aca0314
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 58 deletions.
22 changes: 5 additions & 17 deletions src/audio_effects/Robotization.cpp
Expand Up @@ -34,7 +34,7 @@
using namespace openshot;

/// Blank constructor, useful when using Json to load the effect properties
Robotization::Robotization() : fft_size(FFT_SIZE_2048), hop_size(HOP_SIZE_8), window_type(RECTANGULAR), effect_type(ROBOTIZATION), stft(*this) {
Robotization::Robotization() : fft_size(FFT_SIZE_512), hop_size(HOP_SIZE_2), window_type(RECTANGULAR), effect_type(ROBOTIZATION), stft(*this) {
// Init effect properties
init_effect_details();
}
Expand All @@ -52,7 +52,6 @@ void Robotization::init_effect_details()
{
/// Initialize the values of the EffectInfo struct.
InitEffectInfo();
// stft = RobotizationWhisperizationEffect(*this);

/// Set the effect info
info.class_name = "Robotization";
Expand All @@ -69,30 +68,19 @@ std::shared_ptr<openshot::Frame> Robotization::GetFrame(std::shared_ptr<openshot
const ScopedLock sl (lock);
ScopedNoDenormals noDenormals;

// const ScopedLock sl (lock);
// ScopedNoDenormals noDenormals;

// copy of the AudioBuffer frame->audio object (not the pointer)
// input_buffer = std::make_shared<juce::AudioBuffer<float>>(*frame->audio);
// output_buffer = std::make_shared<juce::AudioBuffer<float>>(*frame->audio);
// frame->audio;

const int num_input_channels = frame->audio->getNumChannels();
const int num_output_channels = frame->audio->getNumChannels();
const int num_samples = frame->audio->getNumSamples();
const int hop_size_value = 1 << ((int)hop_size + 1);
const int fft_size_value = 1 << ((int)fft_size + 5);

stft.setup(num_input_channels);
stft.setup(num_output_channels);
stft.updateParameters((int)fft_size_value,
(int)hop_size_value,
(int)window_type);

stft.process(*frame->audio);

for (int channel = num_input_channels; channel < num_output_channels; ++channel)
frame->audio->clear(channel, 0, num_samples);

// return the modified frame
return frame;
}
Expand Down Expand Up @@ -188,9 +176,9 @@ std::string Robotization::PropertiesJSON(int64_t requested_frame) const {
root["fft_size"]["choices"].append(add_property_choice_json("8192", FFT_SIZE_8192, fft_size));

// Add hop_size choices (dropdown style)
root["hop_size"]["choices"].append(add_property_choice_json("2", HOP_SIZE_2, hop_size));
root["hop_size"]["choices"].append(add_property_choice_json("4", HOP_SIZE_4, hop_size));
root["hop_size"]["choices"].append(add_property_choice_json("8", HOP_SIZE_8, hop_size));
root["hop_size"]["choices"].append(add_property_choice_json("1/2", HOP_SIZE_2, hop_size));
root["hop_size"]["choices"].append(add_property_choice_json("1/4", HOP_SIZE_4, hop_size));
root["hop_size"]["choices"].append(add_property_choice_json("1/8", HOP_SIZE_8, hop_size));

// Add window_type choices (dropdown style)
root["window_type"]["choices"].append(add_property_choice_json("Rectangular", RECTANGULAR, window_type));
Expand Down
16 changes: 8 additions & 8 deletions src/audio_effects/Robotization.h
Expand Up @@ -123,19 +123,19 @@ namespace openshot
}
case ROBOTIZATION: {
for (int index = 0; index < fft_size; ++index) {
float magnitude = abs (frequency_domain_buffer[index]);
frequency_domain_buffer[index].real (magnitude);
frequency_domain_buffer[index].imag (0.0f);
float magnitude = abs(frequency_domain_buffer[index]);
frequency_domain_buffer[index].real(magnitude);
frequency_domain_buffer[index].imag(0.0f);
}
break;
}
case WHISPERIZATION: {
for (int index = 0; index < fft_size / 2 + 1; ++index) {
float magnitude = abs (frequency_domain_buffer[index]);
float magnitude = abs(frequency_domain_buffer[index]);
float phase = 2.0f * M_PI * (float)rand() / (float)RAND_MAX;

frequency_domain_buffer[index].real (magnitude * cosf (phase));
frequency_domain_buffer[index].imag (magnitude * sinf (phase));
frequency_domain_buffer[index].real(magnitude * cosf (phase));
frequency_domain_buffer[index].imag(magnitude * sinf (phase));
if (index > 0 && index < fft_size / 2) {
frequency_domain_buffer[fft_size - index].real (magnitude * cosf (phase));
frequency_domain_buffer[fft_size - index].imag (magnitude * sinf (-phase));
Expand All @@ -145,10 +145,10 @@ namespace openshot
}
}

fft->perform (frequency_domain_buffer, time_domain_buffer, true);
fft->perform(frequency_domain_buffer, time_domain_buffer, true);
}

Robotization& parent;
Robotization &parent;
};

juce::CriticalSection lock;
Expand Down
74 changes: 41 additions & 33 deletions src/audio_effects/STFT.cpp
Expand Up @@ -19,30 +19,31 @@ void STFT::process(juce::AudioSampleBuffer &block)
num_samples = block.getNumSamples();

for (int channel = 0; channel < num_channels; ++channel) {
float* channelData = block.getWritePointer (channel);
float *channel_data = block.getWritePointer(channel);

current_input_buffer_write_position = input_buffer_write_position;
current_output_buffer_write_position = output_buffer_write_position;
current_output_buffer_read_position = output_buffer_read_position;
current_samples_since_last_FFT = samples_since_last_FFT;

for (int sample = 0; sample < num_samples; ++sample) {
const float inputSample = channelData[sample];
input_buffer.setSample (channel, current_input_buffer_write_position, inputSample);
const float input_sample = channel_data[sample];

input_buffer.setSample(channel, current_input_buffer_write_position, input_sample);
if (++current_input_buffer_write_position >= input_buffer_length)
current_input_buffer_write_position = 0;

channelData[sample] = output_buffer.getSample (channel, current_output_buffer_read_position);
channel_data[sample] = output_buffer.getSample(channel, current_output_buffer_read_position);

output_buffer.setSample (channel, current_output_buffer_read_position, 0.0f);
output_buffer.setSample(channel, current_output_buffer_read_position, 0.0f);
if (++current_output_buffer_read_position >= output_buffer_length)
current_output_buffer_read_position = 0;

if (++current_samples_since_last_FFT >= hop_size) {
current_samples_since_last_FFT = 0;
analysis (channel);
analysis(channel);
modification();
synthesis (channel);
synthesis(channel);
}
}
}
Expand All @@ -53,41 +54,48 @@ void STFT::process(juce::AudioSampleBuffer &block)
samples_since_last_FFT = current_samples_since_last_FFT;
}


void STFT::updateFftSize(const int new_fft_size)
{
fft_size = new_fft_size;
fft = std::make_unique<juce::dsp::FFT>(log2 (fft_size));

input_buffer_length = fft_size;
input_buffer.clear();
input_buffer.setSize(num_channels, input_buffer_length);
if (new_fft_size != fft_size)
{
fft_size = new_fft_size;
fft = std::make_unique<juce::dsp::FFT>(log2(fft_size));

output_buffer_length = fft_size;
output_buffer.clear();
output_buffer.setSize(num_channels, output_buffer_length);
input_buffer_length = fft_size;
input_buffer.clear();
input_buffer.setSize(num_channels, input_buffer_length);

fft_window.realloc(fft_size);
fft_window.clear(fft_size);
output_buffer_length = fft_size;
output_buffer.clear();
output_buffer.setSize(num_channels, output_buffer_length);

time_domain_buffer.realloc(fft_size);
time_domain_buffer.clear(fft_size);
fft_window.realloc(fft_size);
fft_window.clear(fft_size);

frequency_domain_buffer.realloc(fft_size);
frequency_domain_buffer.clear(fft_size);
time_domain_buffer.realloc(fft_size);
time_domain_buffer.clear(fft_size);

input_buffer_write_position = 0;
output_buffer_write_position = 0;
output_buffer_read_position = 0;
samples_since_last_FFT = 0;
frequency_domain_buffer.realloc(fft_size);
frequency_domain_buffer.clear(fft_size);

input_buffer_write_position = 0;
output_buffer_write_position = 0;
output_buffer_read_position = 0;
samples_since_last_FFT = 0;
}
}

void STFT::updateHopSize(const int new_overlap)
{
overlap = new_overlap;
if (new_overlap != overlap)
{
overlap = new_overlap;

if (overlap != 0) {
hop_size = fft_size / overlap;
output_buffer_write_position = hop_size % output_buffer_length;
if (overlap != 0) {
hop_size = fft_size / overlap;
output_buffer_write_position = hop_size % output_buffer_length;
}
}
}

Expand Down Expand Up @@ -129,7 +137,7 @@ void STFT::analysis(const int channel)
{
int input_buffer_index = current_input_buffer_write_position;
for (int index = 0; index < fft_size; ++index) {
time_domain_buffer[index].real(fft_window[index] * input_buffer.getSample (channel, input_buffer_index));
time_domain_buffer[index].real(fft_window[index] * input_buffer.getSample(channel, input_buffer_index));
time_domain_buffer[index].imag(0.0f);

if (++input_buffer_index >= input_buffer_length)
Expand Down Expand Up @@ -161,9 +169,9 @@ void STFT::synthesis(const int channel)
{
int output_buffer_index = current_output_buffer_write_position;
for (int index = 0; index < fft_size; ++index) {
float output_sample = output_buffer.getSample (channel, output_buffer_index);
float output_sample = output_buffer.getSample(channel, output_buffer_index);
output_sample += time_domain_buffer[index].real() * window_scale_factor;
output_buffer.setSample (channel, output_buffer_index, output_sample);
output_buffer.setSample(channel, output_buffer_index, output_sample);

if (++output_buffer_index >= output_buffer_length)
output_buffer_index = 0;
Expand Down

0 comments on commit aca0314

Please sign in to comment.