/* * CINELERRA * Copyright (C) 2008-2019 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 */ #ifndef REVERB_H #define REVERB_H class Reverb; class ReverbEngine; class ReverbFFT; #include "compressortools.h" #include "fourier.h" #include "reverbwindow.h" #include "loadbalance.h" #include "pluginaclient.h" #define MAX_DELAY_INIT 1000 #define MIN_REFLECTIONS 1 #define MAX_REFLECTIONS 255 #define MIN_REFLENGTH 3 #define MAX_REFLENGTH 5000 class ReverbConfig { public: ReverbConfig(); int equivalent(ReverbConfig &that); void copy_from(ReverbConfig &that); void interpolate(ReverbConfig &prev, ReverbConfig &next, int64_t prev_frame, int64_t next_frame, int64_t current_frame); void dump(); void boundaries(); float level_init; int delay_init; float ref_level1; float ref_level2; int ref_total; int ref_length; // high frequency int high; // low frequency int low; float q; int window_size; }; class Reverb : public PluginAClient { public: Reverb(PluginServer *server); ~Reverb(); void reset(); void render_stop(); void update_gui(); // required for all realtime/multichannel plugins PLUGIN_CLASS_MEMBERS(ReverbConfig); int process_buffer(int64_t size, Samples **buffer, int64_t start_position, int sample_rate); double gauss(double sigma, double center, double x); void calculate_envelope(); void reallocate_dsp(int new_dsp_allocated); int is_realtime(); int is_synthesis(); int is_multichannel(); void save_data(KeyFrame *keyframe); void read_data(KeyFrame *keyframe); // the output all reflections are painted on double **dsp_in; // may have to expand it for fft windows larger than the reflected time int dsp_in_allocated; // total samples read into dsp_in by the FFT int dsp_in_length; // new value calculated by the FFT readers int new_dsp_length; // total spectrogram frames generated by the FFT. Each channel overwrites the same // spectrograms int new_spectrogram_frames; // source channels of reflections int **ref_channels; // destination offsets of reflections int **ref_offsets; // levels of reflections double **ref_levels; // detect seeking int64_t last_position; // start_position / sample_rate double start_pos; // get_direction fwd=1, rev=-1, stop=0 int dir; DB db; ReverbEngine *engine; ReverbFFT **fft; double *envelope; int need_reconfigure; }; class ReverbClientFrame : public CompressorFreqFrame { public: ReverbClientFrame(int size); ~ReverbClientFrame(); }; class ReverbFFT :public CrossfadeFFT { public: ReverbFFT(Reverb *plugin, int channel); ~ReverbFFT(); int signal_process(); int post_process(); int read_samples(int64_t output_sample, int samples, Samples *buffer); Reverb *plugin; ReverbClientFrame *frame; int channel; }; class ReverbPackage : public LoadPackage { public: ReverbPackage(); int channel; }; class ReverbUnit : public LoadClient { public: ReverbUnit(ReverbEngine *engine, Reverb *plugin); ~ReverbUnit(); void process_package(LoadPackage *package); ReverbEngine *engine; Reverb *plugin; }; // This allocates 1 CPU for each output channel. // They simultaneously read from all the input FFT channels. class ReverbEngine : public LoadServer { public: ReverbEngine(Reverb *plugin); ~ReverbEngine(); void init_packages(); LoadClient* new_client(); LoadPackage* new_package(); Reverb *plugin; }; #endif