X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Fplugins%2Freverb%2Freverb.C;fp=cinelerra-5.0%2Fplugins%2Freverb%2Freverb.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=d309465eed8de97f3e2e9552d68e744e40b4f66b;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/plugins/reverb/reverb.C b/cinelerra-5.0/plugins/reverb/reverb.C deleted file mode 100644 index d309465e..00000000 --- a/cinelerra-5.0/plugins/reverb/reverb.C +++ /dev/null @@ -1,602 +0,0 @@ - -/* - * CINELERRA - * Copyright (C) 2008 Adam Williams - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include "clip.h" -#include "confirmsave.h" -#include "bchash.h" -#include "bcsignals.h" -#include "errorbox.h" -#include "filexml.h" -#include "format.inc" -#include "language.h" -#include "reverb.h" -#include "reverbwindow.h" -#include "samples.h" -#include "units.h" - -#include "vframe.h" - -#include -#include -#include -#include - - - -PluginClient* new_plugin(PluginServer *server) -{ - return new Reverb(server); -} - - - -Reverb::Reverb(PluginServer *server) - : PluginAClient(server) -{ - srand(time(0)); - redo_buffers = 1; // set to redo buffers before the first render - dsp_in_length = 0; - ref_channels = 0; - ref_offsets = 0; - ref_levels = 0; - ref_lowpass = 0; - dsp_in = 0; - lowpass_in1 = 0; - lowpass_in2 = 0; - initialized = 0; - -} - -Reverb::~Reverb() -{ - - - if(initialized) - { - for(int i = 0; i < total_in_buffers; i++) - { - delete [] dsp_in[i]; - delete [] ref_channels[i]; - delete [] ref_offsets[i]; - delete [] ref_levels[i]; - delete [] ref_lowpass[i]; - delete [] lowpass_in1[i]; - delete [] lowpass_in2[i]; - } - - delete [] dsp_in; - delete [] ref_channels; - delete [] ref_offsets; - delete [] ref_levels; - delete [] ref_lowpass; - delete [] lowpass_in1; - delete [] lowpass_in2; - - for(int i = 0; i < (smp + 1); i++) - { - delete engine[i]; - } - delete [] engine; - initialized = 0; - } -} - -const char* Reverb::plugin_title() { return _("Reverb"); } -int Reverb::is_realtime() { return 1; } -int Reverb::is_multichannel() { return 1; } -int Reverb::is_synthesis() { return 1; } - -int Reverb::process_realtime(int64_t size, - Samples **input_ptr, - Samples **output_ptr) -{ - int64_t new_dsp_length, i, j; - main_in = new double*[total_in_buffers]; - main_out = new double*[total_in_buffers]; - - for(i = 0; i < total_in_buffers; i++) - { - main_in[i] = input_ptr[i]->get_data(); - main_out[i] = output_ptr[i]->get_data(); - } - -//printf("Reverb::process_realtime 1\n"); - redo_buffers |= load_configuration(); - -//printf("Reverb::process_realtime 1\n"); - if(!config.ref_total) - { - delete [] main_in; - delete [] main_out; - return 0; - } - - - if(!initialized) - { - dsp_in = new double*[total_in_buffers]; - ref_channels = new int64_t*[total_in_buffers]; - ref_offsets = new int64_t*[total_in_buffers]; - ref_levels = new double*[total_in_buffers]; - ref_lowpass = new int64_t*[total_in_buffers]; - lowpass_in1 = new double*[total_in_buffers]; - lowpass_in2 = new double*[total_in_buffers]; - - - - for(i = 0; i < total_in_buffers; i++) - { - dsp_in[i] = new double[1]; - ref_channels[i] = new int64_t[1]; - ref_offsets[i] = new int64_t[1]; - ref_levels[i] = new double[1]; - ref_lowpass[i] = new int64_t[1]; - lowpass_in1[i] = new double[1]; - lowpass_in2[i] = new double[1]; - } - - engine = new ReverbEngine*[(smp + 1)]; - for(i = 0; i < (smp + 1); i++) - { - engine[i] = new ReverbEngine(this); -//printf("Reverb::start_realtime %d\n", Thread::calculate_realtime()); -// Realtime priority moved to sound driver -// engine[i]->set_realtime(realtime_priority); - engine[i]->start(); - } - initialized = 1; - redo_buffers = 1; - } - - new_dsp_length = size + - ((int64_t)config.delay_init + config.ref_length) * project_sample_rate / 1000 + 1; - - if(redo_buffers || new_dsp_length != dsp_in_length) - { - for(i = 0; i < total_in_buffers; i++) - { - double *old_dsp = dsp_in[i]; - double *new_dsp = new double[new_dsp_length]; - for(j = 0; j < dsp_in_length && j < new_dsp_length; j++) - new_dsp[j] = old_dsp[j]; - - - for( ; j < new_dsp_length; j++) new_dsp[j] = 0; - delete [] old_dsp; - dsp_in[i] = new_dsp; - } - - dsp_in_length = new_dsp_length; - redo_buffers = 1; - } -//printf("Reverb::process_realtime 1\n"); - - if(redo_buffers) - { - for(i = 0; i < total_in_buffers; i++) - { - delete [] ref_channels[i]; - delete [] ref_offsets[i]; - delete [] ref_lowpass[i]; - delete [] ref_levels[i]; - delete [] lowpass_in1[i]; - delete [] lowpass_in2[i]; - - ref_channels[i] = new int64_t[config.ref_total + 1]; - ref_offsets[i] = new int64_t[config.ref_total + 1]; - ref_lowpass[i] = new int64_t[config.ref_total + 1]; - ref_levels[i] = new double[config.ref_total + 1]; - lowpass_in1[i] = new double[config.ref_total + 1]; - lowpass_in2[i] = new double[config.ref_total + 1]; - -// set channels - ref_channels[i][0] = i; // primary noise - ref_channels[i][1] = i; // first reflection -// set offsets - ref_offsets[i][0] = 0; - ref_offsets[i][1] = config.delay_init * project_sample_rate / 1000; -// set levels - ref_levels[i][0] = db.fromdb(config.level_init); - ref_levels[i][1] = db.fromdb(config.ref_level1); -// set lowpass - ref_lowpass[i][0] = -1; // ignore first noise - ref_lowpass[i][1] = config.lowpass1; - lowpass_in1[i][0] = 0; - lowpass_in2[i][0] = 0; - lowpass_in1[i][1] = 0; - lowpass_in2[i][1] = 0; - - int64_t ref_division = config.ref_length * project_sample_rate / 1000 / (config.ref_total + 1); - for(j = 2; j < config.ref_total + 1; j++) - { -// set random channels for remaining reflections - ref_channels[i][j] = rand() % total_in_buffers; - -// set random offsets after first reflection - ref_offsets[i][j] = ref_offsets[i][1]; - ref_offsets[i][j] += ref_division * j - (rand() % ref_division) / 2; - -// set changing levels - ref_levels[i][j] = db.fromdb(config.ref_level1 + (config.ref_level2 - config.ref_level1) / (config.ref_total - 1) * (j - 2)); - //ref_levels[i][j] /= 100; - -// set changing lowpass as linear - ref_lowpass[i][j] = (int64_t)(config.lowpass1 + (double)(config.lowpass2 - config.lowpass1) / (config.ref_total - 1) * (j - 2)); - lowpass_in1[i][j] = 0; - lowpass_in2[i][j] = 0; - } - } - - redo_buffers = 0; - } -//printf("Reverb::process_realtime 1\n"); - - for(i = 0; i < total_in_buffers; ) - { - for(j = 0; j < (smp + 1) && (i + j) < total_in_buffers; j++) - { - engine[j]->process_overlays(i + j, size); - } - - for(j = 0; j < (smp + 1) && i < total_in_buffers; j++, i++) - { - engine[j]->wait_process_overlays(); - } - } -//printf("Reverb::process_realtime 2 %d %d\n", total_in_buffers, size); - - for(i = 0; i < total_in_buffers; i++) - { - double *current_out = main_out[i]; - double *current_in = dsp_in[i]; - - for(j = 0; j < size; j++) current_out[j] = current_in[j]; - - int64_t k; - for(k = 0; j < dsp_in_length; j++, k++) current_in[k] = current_in[j]; - - for(; k < dsp_in_length; k++) current_in[k] = 0; - } -//printf("Reverb::process_realtime 2 %d %d\n", total_in_buffers, size); - - - delete [] main_in; - delete [] main_out; - return 0; -} - - -NEW_WINDOW_MACRO(Reverb, ReverbWindow) - - -LOAD_CONFIGURATION_MACRO(Reverb, ReverbConfig) - - -void Reverb::save_data(KeyFrame *keyframe) -{ -//printf("Reverb::save_data 1\n"); - FileXML output; -//printf("Reverb::save_data 1\n"); - -// cause xml file to store data directly in text - output.set_shared_output(keyframe->get_data(), MESSAGESIZE); -//printf("Reverb::save_data 1\n"); - - output.tag.set_title("REVERB"); - output.tag.set_property("LEVELINIT", config.level_init); - output.tag.set_property("DELAY_INIT", config.delay_init); - output.tag.set_property("REF_LEVEL1", config.ref_level1); - output.tag.set_property("REF_LEVEL2", config.ref_level2); - output.tag.set_property("REF_TOTAL", config.ref_total); -//printf("Reverb::save_data 1\n"); - output.tag.set_property("REF_LENGTH", config.ref_length); - output.tag.set_property("LOWPASS1", config.lowpass1); - output.tag.set_property("LOWPASS2", config.lowpass2); -//printf("Reverb::save_data config.ref_level2 %f\n", config.ref_level2); - output.append_tag(); - output.tag.set_title("/REVERB"); - output.append_tag(); - output.append_newline(); - output.terminate_string(); -//printf("Reverb::save_data 2\n"); -} - -void Reverb::read_data(KeyFrame *keyframe) -{ - FileXML input; -// cause xml file to read directly from text - input.set_shared_input(keyframe->get_data(), strlen(keyframe->get_data())); - int result = 0; - - result = input.read_tag(); - - if(!result) - { - if(input.tag.title_is("REVERB")) - { - config.level_init = input.tag.get_property("LEVELINIT", config.level_init); - config.delay_init = input.tag.get_property("DELAY_INIT", config.delay_init); - config.ref_level1 = input.tag.get_property("REF_LEVEL1", config.ref_level1); - config.ref_level2 = input.tag.get_property("REF_LEVEL2", config.ref_level2); - config.ref_total = input.tag.get_property("REF_TOTAL", config.ref_total); - config.ref_length = input.tag.get_property("REF_LENGTH", config.ref_length); - config.lowpass1 = input.tag.get_property("LOWPASS1", config.lowpass1); - config.lowpass2 = input.tag.get_property("LOWPASS2", config.lowpass2); - } - } - - config.boundaries(); -} - -void Reverb::update_gui() -{ - if(thread) - { - thread->window->lock_window(); - ((ReverbWindow*)thread->window)->level_init->update(config.level_init); - ((ReverbWindow*)thread->window)->delay_init->update(config.delay_init); - ((ReverbWindow*)thread->window)->ref_level1->update(config.ref_level1); - ((ReverbWindow*)thread->window)->ref_level2->update(config.ref_level2); - ((ReverbWindow*)thread->window)->ref_total->update(config.ref_total); - ((ReverbWindow*)thread->window)->ref_length->update(config.ref_length); - ((ReverbWindow*)thread->window)->lowpass1->update(config.lowpass1); - ((ReverbWindow*)thread->window)->lowpass2->update(config.lowpass2); - thread->window->unlock_window(); - } -} - - - - -int Reverb::load_from_file(char *path) -{ - int result = 0; - int length; - char string[1024]; - - FILE *in = fopen(path, "rb"); - if( in ) - { - fseek(in, 0, SEEK_END); - length = ftell(in); - fseek(in, 0, SEEK_SET); - (void)fread(string, length, 1, in); - fclose(in); -// read_data(string); - } - else - { - perror("fopen:"); -// failed - ErrorBox errorbox(""); - char string[1024]; - sprintf(string, _("Couldn't open %s."), path); - errorbox.create_objects(string); - errorbox.run_window(); - result = 1; - } - - return result; -} - -int Reverb::save_to_file(char *path) -{ - int result = 0; - char string[1024]; - - { -// ConfirmSave confirm; -// result = confirm.test_file("", path); - } - - if(!result) - { - FILE *out = fopen(path, "wb"); - if( out ) - { -// save_data(string); - fwrite(string, strlen(string), 1, out); - fclose(out); - } - else - { - result = 1; -// failed - ErrorBox errorbox(""); - char string[1024]; - sprintf(string, _("Couldn't save %s."), path); - errorbox.create_objects(string); - errorbox.run_window(); - result = 1; - } - } - - return result; -} - -ReverbEngine::ReverbEngine(Reverb *plugin) - : Thread(1, 0, 0) -{ - this->plugin = plugin; - completed = 0; - input_lock.lock(); - output_lock.lock(); -} - -ReverbEngine::~ReverbEngine() -{ - completed = 1; - input_lock.unlock(); - join(); -} - -int ReverbEngine::process_overlays(int output_buffer, int64_t size) -{ - this->output_buffer = output_buffer; - this->size = size; - input_lock.unlock(); - return 0; -} - -int ReverbEngine::wait_process_overlays() -{ - output_lock.lock(); - return 0; -} - -int ReverbEngine::process_overlay(double *in, double *out, double &out1, double &out2, double level, int64_t lowpass, int64_t samplerate, int64_t size) -{ -// Modern niquist frequency is 44khz but pot limit is 20khz so can't use -// niquist - if(lowpass == -1 || lowpass >= 20000) - { -// no lowpass filter - for(int i = 0; i < size; i++) out[i] += in[i] * level; - } - else - { - double coef = 0.25 * 2.0 * M_PI * (double)lowpass / (double)plugin->project_sample_rate; - double a = coef * 0.25; - double b = coef * 0.50; - - for(int i = 0; i < size; i++) - { - out2 += a * (3 * out1 + in[i] - out2); - out2 += b * (out1 + in[i] - out2); - out2 += a * (out1 + 3 * in[i] - out2); - out2 += coef * (in[i] - out2); - out1 = in[i]; - out[i] += out2 * level; - } - } - return 0; -} - -void ReverbEngine::run() -{ - int j, i; -//printf("ReverbEngine::run 1 %d\n", calculate_realtime()); - while(1) - { - input_lock.lock(); - if(completed) return; - -// Process reverb - for(i = 0; i < plugin->total_in_buffers; i++) - { - for(j = 0; j < plugin->config.ref_total + 1; j++) - { - if(plugin->ref_channels[i][j] == output_buffer) - process_overlay(plugin->main_in[i], - &(plugin->dsp_in[plugin->ref_channels[i][j]][plugin->ref_offsets[i][j]]), - plugin->lowpass_in1[i][j], - plugin->lowpass_in2[i][j], - plugin->ref_levels[i][j], - plugin->ref_lowpass[i][j], - plugin->project_sample_rate, - size); - } - } - - output_lock.unlock(); - } -} - - - - - - - -ReverbConfig::ReverbConfig() -{ - level_init = 0; - delay_init = 0; - ref_level1 = -20; - ref_level2 = INFINITYGAIN; - ref_total = 100; - ref_length = 600; - lowpass1 = Freq::tofreq(TOTALFREQS); - lowpass2 = Freq::tofreq(TOTALFREQS); - -} - -int ReverbConfig::equivalent(ReverbConfig &that) -{ - return (EQUIV(level_init, that.level_init) && - delay_init == that.delay_init && - EQUIV(ref_level1, that.ref_level1) && - EQUIV(ref_level2, that.ref_level2) && - ref_total == that.ref_total && - ref_length == that.ref_length && - lowpass1 == that.lowpass1 && - lowpass2 == that.lowpass2); -} - -void ReverbConfig::copy_from(ReverbConfig &that) -{ - level_init = that.level_init; - delay_init = that.delay_init; - ref_level1 = that.ref_level1; - ref_level2 = that.ref_level2; - ref_total = that.ref_total; - ref_length = that.ref_length; - lowpass1 = that.lowpass1; - lowpass2 = that.lowpass2; -} - -void ReverbConfig::interpolate(ReverbConfig &prev, - ReverbConfig &next, - int64_t prev_frame, - int64_t next_frame, - int64_t current_frame) -{ - level_init = prev.level_init; - delay_init = prev.delay_init; - ref_level1 = prev.ref_level1; - ref_level2 = prev.ref_level2; - ref_total = prev.ref_total; - ref_length = prev.ref_length; - lowpass1 = prev.lowpass1; - lowpass2 = prev.lowpass2; -} - -void ReverbConfig::boundaries() -{ - - CLAMP(level_init, INFINITYGAIN, 0); - CLAMP(delay_init, 0, MAX_DELAY_INIT); - CLAMP(ref_level1, INFINITYGAIN, 0); - CLAMP(ref_level2, INFINITYGAIN, 0); - CLAMP(ref_total, MIN_REFLECTIONS, MAX_REFLECTIONS); - CLAMP(ref_length, 0, MAX_REFLENGTH); - CLAMP(lowpass1, 0, Freq::tofreq(TOTALFREQS)); - CLAMP(lowpass2, 0, Freq::tofreq(TOTALFREQS)); -} - -void ReverbConfig::dump() -{ - printf("ReverbConfig::dump %f %jd %f %f %jd %jd %jd %jd\n", - level_init, delay_init, ref_level1, ref_level2, - ref_total, ref_length, lowpass1, lowpass2); -} - -