/* * 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 "bcdisplayinfo.h" #include "bchash.h" #include "file.h" #include "language.h" #include "mainprogress.h" #include "normalize.h" #include "normalizewindow.h" #include "samples.h" #include "units.h" #include "vframe.h" #include #include REGISTER_PLUGIN(NormalizeMain) NormalizeMain::NormalizeMain(PluginServer *server) : PluginAClient(server) { } NormalizeMain::~NormalizeMain() { } const char* NormalizeMain::plugin_title() { return N_("Normalize"); } int NormalizeMain::is_realtime() { return 0; } int NormalizeMain::is_multichannel() { return 1; } int NormalizeMain::load_defaults() { char directory[BCTEXTLEN]; // set the default directory sprintf(directory, "%s/normalize.rc", File::get_config_path()); // load the defaults defaults = new BC_Hash(directory); defaults->load(); db_over = defaults->get("DBOVER", 0); separate_tracks = defaults->get("SEPERATE_TRACKS", 1); return 0; } int NormalizeMain::save_defaults() { defaults->update("DBOVER", db_over); defaults->update("SEPERATE_TRACKS", separate_tracks); defaults->save(); return 0; } int NormalizeMain::get_parameters() { BC_DisplayInfo info; NormalizeWindow window(info.get_abs_cursor_x(), info.get_abs_cursor_y()); window.create_objects(&db_over, &separate_tracks); int result = window.run_window(); return result; } int NormalizeMain::start_loop() { char string[BCTEXTLEN]; sprintf(string, "%s...", plugin_title()); progress = start_progress(string, (PluginClient::end - PluginClient::start) * 2); writing = 0; current_position = PluginClient::start; peak = new double[PluginClient::total_in_buffers]; scale = new double[PluginClient::total_in_buffers]; bzero(peak, sizeof(double) * PluginClient::total_in_buffers); return 0; } int NormalizeMain::process_loop(Samples **buffer, int64_t &write_length) { int result = 0; int64_t fragment_len; //printf("NormalizeMain::process_loop 1\n"); if(writing) { fragment_len = PluginClient::in_buffer_size; if(current_position + fragment_len > PluginClient::end) fragment_len = PluginClient::end - current_position; //printf("NormalizeMain::process_loop 2 %d %f\n", current_position, scale[0]); for(int i = 0; i < PluginClient::total_in_buffers; i++) { read_samples(buffer[i], i, current_position, fragment_len); double *buffer_samples = buffer[i]->get_data(); for(int j = 0; j < fragment_len; j++) buffer_samples[j] *= scale[i]; } //printf("NormalizeMain::process_loop 1 %d %f\n", current_position, scale[0]); current_position += fragment_len; write_length = fragment_len; result = progress->update(PluginClient::end - PluginClient::start + current_position - PluginClient::start); if(current_position >= PluginClient::end) result = 1; } else { // Get peak //printf("NormalizeMain::process_loop 4\n"); for(int i = PluginClient::start; i < PluginClient::end && !result; i += fragment_len) { fragment_len = PluginClient::in_buffer_size; if(i + fragment_len > PluginClient::end) fragment_len = PluginClient::end - i; //printf("NormalizeMain::process_loop 5\n"); for(int j = 0; j < PluginClient::total_in_buffers; j++) { //printf("NormalizeMain::process_loop 6 %p\n", buffer); read_samples(buffer[j], j, i, fragment_len); //printf("NormalizeMain::process_loop 7\n"); double *buffer_samples = buffer[j]->get_data(); for(int k = 0; k < fragment_len; k++) { double sample = fabs(buffer_samples[k]); if(peak[j] < sample) peak[j] = sample; } } //printf("NormalizeMain::process_loop 8\n"); result = progress->update(i - PluginClient::start); //printf("NormalizeMain::process_loop 9\n"); } // Normalize all tracks double max = 0; for(int i = 0; i < PluginClient::total_in_buffers; i++) { if(peak[i] > max) max = peak[i]; } if(!separate_tracks) { for(int i = 0; i < PluginClient::total_in_buffers; i++) { peak[i] = max; } } for(int i = 0; i < PluginClient::total_in_buffers; i++) { scale[i] = DB::fromdb(db_over) / peak[i]; } //printf("NormalizeMain::process_loop 10\n"); char string[BCTEXTLEN]; sprintf(string, "%s %.0f%%...", plugin_title(), (DB::fromdb(db_over) / max) * 100); progress->update_title(string); // Start writing on next iteration writing = 1; } return result; } int NormalizeMain::stop_loop() { progress->stop_progress(); delete [] peak; delete [] scale; delete progress; return 0; }