X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcmeter.C;h=673a684a166c39a01a1c1925014de509afb27de5;hp=e4eb2bd91dd5b18c1751f430fa2617c865ca8173;hb=0e6cf5b52d1ebce9272270144bcf43df4683507e;hpb=f068b73c1d4afafbf6d86e7f5bc8f1c96b5366d3 diff --git a/cinelerra-5.1/guicast/bcmeter.C b/cinelerra-5.1/guicast/bcmeter.C index e4eb2bd9..673a684a 100644 --- a/cinelerra-5.1/guicast/bcmeter.C +++ b/cinelerra-5.1/guicast/bcmeter.C @@ -16,7 +16,6 @@ * 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 "bcbutton.h" @@ -24,7 +23,7 @@ #include "bcpixmap.h" #include "bcresources.h" #include "bcwindow.h" -#include "bccolors.h" +#include "colors.h" #include "fonts.h" #include "vframe.h" #include @@ -44,16 +43,9 @@ #define METER_RIGHT 3 -BC_Meter::BC_Meter(int x, - int y, - int orientation, - int pixels, - int min, - int max, - int mode, - int use_titles, - int span, - int downmix) +BC_Meter::BC_Meter(int x, int y, int orientation, int pixels, + int min, int max, int mode, int use_titles, + int span, int is_downmix, int is_gain_change) : BC_SubWindow(x, y, -1, -1) { this->over_delay = 150; @@ -65,10 +57,10 @@ BC_Meter::BC_Meter(int x, this->orientation = orientation; this->pixels = pixels; this->span = span; - this->downmix = downmix; - + this->is_downmix = is_downmix; + this->is_gain_change = is_gain_change; //printf("BC_Meter::draw_face %d w=%d pixels=%d\n", __LINE__, w, pixels); - for(int i = 0; i < TOTAL_METER_IMAGES; i++) images[i] = 0; + for( int i = 0; i < TOTAL_METER_IMAGES; i++ ) images[i] = 0; db_titles.set_array_delete(); } @@ -76,8 +68,9 @@ BC_Meter::~BC_Meter() { db_titles.remove_all_objects(); title_pixels.remove_all(); + tick_w.remove_all(); tick_pixels.remove_all(); - for(int i = 0; i < TOTAL_METER_IMAGES; i++) delete images[i]; + for( int i = 0; i < TOTAL_METER_IMAGES; i++ ) delete images[i]; } int BC_Meter::get_title_w() @@ -104,26 +97,29 @@ int BC_Meter::initialize() level_pixel = peak_pixel = 0; over_timer = 0; over_count = 0; - peak = level = -100; - if(orientation == METER_VERT) - { + if( is_gain_change ) { + peak = level = 0; + } + else { + peak = level = -100; + } + + if( orientation == METER_VERT ) { set_images(get_resources()->ymeter_images); h = pixels; - if(span < 0) - { + if( span < 0 ) { w = images[0]->get_w(); - if(use_titles) w += get_title_w(); + if( use_titles ) w += get_title_w(); } else w = span; } - else - { + else { set_images(get_resources()->xmeter_images); h = images[0]->get_h(); w = pixels; - if(use_titles) h += get_title_w(); + if( use_titles ) h += get_title_w(); } // calibrate the db titles @@ -138,21 +134,19 @@ int BC_Meter::initialize() void BC_Meter::set_images(VFrame **data) { - for(int i = 0; i < TOTAL_METER_IMAGES; i++) delete images[i]; - for(int i = 0; i < TOTAL_METER_IMAGES; i++) + for( int i = 0; i < TOTAL_METER_IMAGES; i++ ) delete images[i]; + for( int i = 0; i < TOTAL_METER_IMAGES; i++ ) images[i] = new BC_Pixmap(parent_window, data[i], PIXMAP_ALPHA); } int BC_Meter::reposition_window(int x, int y, int span, int pixels) { - if(pixels < 0) pixels = this->pixels; + if( pixels < 0 ) pixels = this->pixels; this->span = span; this->pixels = pixels; - if(orientation == METER_VERT) - BC_SubWindow::reposition_window(x, - y, - this->span < 0 ? w : span, - pixels); + if( orientation == METER_VERT ) + BC_SubWindow::reposition_window(x, y, + this->span < 0 ? w : span, pixels); else BC_SubWindow::reposition_window(x, y, pixels, get_h()); @@ -168,7 +162,7 @@ int BC_Meter::reposition_window(int x, int y, int span, int pixels) return 0; } -int BC_Meter::reset(int dmix) +int BC_Meter::reset(int downmix) { level = min; peak = min; @@ -176,15 +170,15 @@ int BC_Meter::reset(int dmix) peak_timer = 0; over_timer = 0; over_count = 0; - if(dmix >= 0) downmix = dmix; + if( downmix >= 0 ) + is_downmix = downmix; draw_face(1); return 0; } int BC_Meter::button_press_event() { - if(cursor_inside() && is_event_win()) - { + if( cursor_inside() && is_event_win() ) { reset_over(); return 1; } @@ -210,15 +204,11 @@ int BC_Meter::change_format(int mode, int min, int max) int BC_Meter::level_to_pixel(float level) { int result; - if(mode == METER_DB) - { - result = (int)(pixels * - (level - min) / - (max - min)); - if(level <= min) result = 0; + if( mode == METER_DB ) { + result = (int)(pixels * (level - min) / (max - min)); + if( level <= min ) result = 0; } - else - { + else { // Not implemented anymore result = 0; } @@ -236,6 +226,7 @@ void BC_Meter::get_divisions() db_titles.remove_all_objects(); title_pixels.remove_all(); tick_pixels.remove_all(); + tick_w.remove_all(); low_division = 0; medium_division = 0; @@ -243,111 +234,104 @@ void BC_Meter::get_divisions() int current_pixel; // Create tick marks and titles in one pass - for(int current = min; current <= max; current++) - { - if(orientation == METER_VERT) - { + for( int current = min; current <= max; current++ ) { + if( orientation == METER_VERT ) { // Create tick mark current_pixel = (pixels - METER_MARGIN * 2 - 2) * (current - min) / (max - min) + 2; tick_pixels.append(current_pixel); // Create titles in selected positions - if(current == min || - current == max || - current == 0 || - (current - min > 4 && max - current > 4 && !(current % 5))) - { - int title_pixel = (pixels - - METER_MARGIN * 2) * (current - min) / (max - min); - sprintf(string, "%ld", labs(current)); + if( current == min || current == max || current == 0 || + (current - min > 4 && max - current > 4 && !(current % 5)) ) { + int title_pixel = (pixels - METER_MARGIN * 2) * + (current - min) / (max - min); + sprintf(string, "%d", (int)labs(current)); new_string = new char[strlen(string) + 1]; strcpy(new_string, string); db_titles.append(new_string); title_pixels.append(title_pixel); + tick_w.append(TICK_W1); + } + else { + tick_w.append(TICK_W2); } } - else - { + else { current_pixel = (pixels - METER_MARGIN * 2) * (current - min) / (max - min); tick_pixels.append(current_pixel); + tick_w.append(TICK_W1); // Titles not supported for horizontal } // Create color divisions - if(current == -20) - { + if( current == -20 ) { low_division = current_pixel; } else - if(current == -5) - { + if( current == -5 ) { medium_division = current_pixel; } else - if(current == 0) - { + if( current == 0 ) { high_division = current_pixel; } } -// if(orientation == METER_VERT) +// if( orientation == METER_VERT ) // printf("BC_Meter::get_divisions %d %d %d %d\n", // low_division, medium_division, high_division, pixels); } void BC_Meter::draw_titles(int flush) { - if(!use_titles) return; + if( !use_titles ) return; + int tick_xfudge = xS(1); set_font(get_resources()->meter_font); - if(orientation == METER_HORIZ) - { + if( orientation == METER_HORIZ ) { draw_top_background(parent_window, 0, 0, get_w(), get_title_w()); - for(int i = 0; i < db_titles.total; i++) - { + for( int i = 0; i < db_titles.total; i++ ) { draw_text(0, title_pixels.values[i], db_titles.values[i]); } flash(0, 0, get_w(), get_title_w(), flush); } else - if(orientation == METER_VERT) - { + if( orientation == METER_VERT ) { draw_top_background(parent_window, 0, 0, get_title_w(), get_h()); // Titles - for(int i = 0; i < db_titles.total; i++) - { - int title_y = pixels - - title_pixels.values[i]; - if(i == 0) - title_y -= get_text_descent(SMALLFONT_3D); + for( int i = 0; i < db_titles.total; i++ ) { + int title_y = pixels - title_pixels.values[i]; + if( i == 0 ) + title_y -= get_text_descent(get_resources()->meter_font); else - if(i == db_titles.total - 1) - title_y += get_text_ascent(SMALLFONT_3D); + if( i == db_titles.total - 1 ) + title_y += get_text_ascent(get_resources()->meter_font); else - title_y += get_text_ascent(SMALLFONT_3D) / 2; + title_y += get_text_ascent(get_resources()->meter_font) / 2; + int title_x = get_title_w() - TICK_W1 - tick_xfudge - + get_text_width(get_resources()->meter_font, db_titles.values[i]); set_color(get_resources()->meter_font_color); - draw_text(0, - title_y, - db_titles.values[i]); + draw_text(title_x, title_y, db_titles.values[i]); } - for(int i = 0; i < tick_pixels.total; i++) - { + for( int i = 0; i < tick_pixels.total; i++ ) { // Tick marks int tick_y = pixels - tick_pixels.values[i] - METER_MARGIN; set_color(get_resources()->meter_font_color); - draw_line(get_title_w() - xS(10) - 1, tick_y, get_title_w() - 1, tick_y); - if(get_resources()->meter_3d) - { + draw_line(get_title_w() - tick_w.get(i) - tick_xfudge, + tick_y, get_title_w() - tick_xfudge, tick_y); + + if( get_resources()->meter_3d ) { set_color(BLACK); - draw_line(get_title_w() - xS(10), tick_y + 1, get_title_w(), tick_y + 1); + draw_line(get_title_w() - tick_w.get(i), + tick_y + 1, get_title_w(), tick_y + 1); } } @@ -358,9 +342,9 @@ void BC_Meter::draw_titles(int flush) int BC_Meter::region_pixel(int region) { VFrame **reference_images = get_resources()->xmeter_images; - int result; + int result = 0; - if(region == METER_RIGHT) + if( region == METER_RIGHT ) result = region * reference_images[0]->get_w() / 4; else result = region * reference_images[0]->get_w() / 4; @@ -377,7 +361,7 @@ int BC_Meter::region_pixels(int region) x1 = region * reference_images[0]->get_w() / 4; x2 = (region + 1) * reference_images[0]->get_w() / 4; - if(region == METER_MID) + if( region == METER_MID ) result = (x2 - x1) * 2; else result = x2 - x1; @@ -400,197 +384,258 @@ void BC_Meter::draw_face(int flush) draw_top_background(parent_window, x, 0, w, h); // printf("BC_Meter::draw_face %d span=%d this->w=%d get_title_w()=%d %d %d\n", -// __LINE__, -// span, -// this->w, -// get_title_w(), -// w, -// h); - - while(pixel < pixels) - { -// Select image to draw - if(pixel < level_pixel || - (pixel >= peak_pixel1 && pixel < peak_pixel2)) - { - if(pixel < low_division) - image_number = METER_GREEN; - else - if(pixel < medium_division) - image_number = METER_YELLOW; - else - if(pixel < high_division) - image_number = METER_RED; - else - image_number = METER_WHITE; - } - else - { - image_number = METER_NORMAL; - } +// __LINE__, span, this->w, get_title_w(), w, h); + if( is_gain_change ) { + int in_h = images[0]->get_h(); + int in_third = in_h / 3; + int in_third3 = in_h - in_third * 2; -// Select region of image to duplicate - if(pixel < left_pixel) - { - region = METER_LEFT; - in_start = pixel + region_pixel(region); - in_span = region_pixels(region) - (in_start - region_pixel(region)); - } - else - if(pixel < right_pixel) - { - region = METER_MID; - in_start = region_pixel(region); - in_span = region_pixels(region); - } - else - { - region = METER_RIGHT; - in_start = (pixel - right_pixel) + region_pixel(region); - in_span = region_pixels(region) - (in_start - region_pixel(region));; +// printf("BC_Meter::draw_face %d level=%f level_pixel=%d high_division=%d\n", +// __LINE__, level, level_pixel, high_division); + + +// fudge a line when no gain change + if( level_pixel == high_division ) { + level_pixel += 1; } -//printf("BC_Meter::draw_face region %d pixel %d pixels %d in_start %d in_span %d\n", region, pixel, pixels, in_start, in_span); - if(in_span > 0) - { -// Clip length to peaks - if(pixel < level_pixel && pixel + in_span > level_pixel) - in_span = level_pixel - pixel; - else - if(pixel < peak_pixel1 && pixel + in_span > peak_pixel1) - in_span = peak_pixel1 - pixel; - else - if(pixel < peak_pixel2 && pixel + in_span > peak_pixel2) - in_span = peak_pixel2 - pixel; + while( pixel < pixels ) { +// Select image to draw & extents + if( level_pixel < high_division ) { +// always vertical + if( pixel < level_pixel ) { + image_number = METER_NORMAL; + in_span = level_pixel - pixel; + } + else + if( pixel < high_division ) { + image_number = METER_RED; + in_span = high_division - pixel; + } + else { + image_number = METER_NORMAL; + in_span = pixels - pixel; + } + } + else { +// determine pixel range & image to draw + if( pixel < high_division ) { + image_number = METER_NORMAL; + in_span = high_division - pixel; + } + else + if( pixel < level_pixel ) { + image_number = METER_GREEN; + in_span = level_pixel - pixel; + } + else { + image_number = METER_NORMAL; + in_span = pixels - pixel; + } + } -// Clip length to color changes - if(image_number == METER_GREEN && pixel + in_span > low_division) - in_span = low_division - pixel; +// determine starting point in source to draw +// draw starting section + if( pixel == 0 ) { + in_start = 0; + } else - if(image_number == METER_YELLOW && pixel + in_span > medium_division) - in_span = medium_division - pixel; +// draw middle section + if( pixels - pixel > in_third3 ) { + in_start = in_third; + } else - if(image_number == METER_RED && pixel + in_span > high_division) - in_span = high_division - pixel; +// draw last section + { + in_start = in_third * 2; + } -// Clip length to regions - if(pixel < left_pixel && pixel + in_span > left_pixel) - in_span = left_pixel - pixel; +// clamp the region to the source dimensions + if( in_start < in_third * 2 ) { + if( in_span > in_third ) { + in_span = in_third; + } + } else - if(pixel < right_pixel && pixel + in_span > right_pixel) - in_span = right_pixel - pixel; +// last segment + if( pixels - pixel < in_third3 ) { + in_span = pixels - pixel; + in_start = in_h - in_span; + } -//printf("BC_Meter::draw_face image_number %d pixel %d pixels %d in_start %d in_span %d\n", image_number, pixel, pixels, in_start, in_span); -//printf("BC_Meter::draw_face %d %d %d %d\n", orientation, region, images[image_number]->get_h() - in_start - in_span); - if(orientation == METER_HORIZ) - { - draw_pixmap(images[image_number], - pixel, - x, - in_span + 1, - get_h(), - in_start, - 0); +// printf("BC_Meter::draw_face %d dst_y=%d src_y=%d" +// " pixels=%d pixel=%d in_h=%d in_start=%d in_span=%d in_third=%d in_third3=%d\n", +// __LINE__, get_h() - pixel - in_span, in_h - in_start - in_span, +// pixels, pixel, in_h, in_start, in_span, in_third, in_third3); + draw_pixmap(images[image_number], x, get_h() - pixel - in_span, + get_w(), in_span + 1, 0, in_h - in_start - in_span); + pixel += in_span; + } + } + else { + while( pixel < pixels ) { +// Select image to draw + if( pixel < level_pixel || + (pixel >= peak_pixel1 && pixel < peak_pixel2) ) { + if( pixel < low_division ) + image_number = METER_GREEN; + else + if( pixel < medium_division ) + image_number = METER_YELLOW; + else + if( pixel < high_division ) + image_number = METER_RED; + else + image_number = METER_WHITE; + } + else { + image_number = METER_NORMAL; + } + +// Select region of image to duplicate + if( pixel < left_pixel ) { + region = METER_LEFT; + in_start = pixel + region_pixel(region); + in_span = region_pixels(region) - (in_start - region_pixel(region)); } else - { -//printf("BC_Meter::draw_face %d %d\n", __LINE__, span); - if(span < 0) - { - draw_pixmap(images[image_number], - x, - get_h() - pixel - in_span, - get_w(), - in_span + 1, - 0, - images[image_number]->get_h() - in_start - in_span); - } - else - { - int total_w = get_w() - x; - int third = images[image_number]->get_w() / 3 + 1; - - - for(int x1 = 0; x1 < total_w; x1 += third) - { - int in_x = 0; - int in_w = third; - if(x1 >= third) in_x = third; - if(x1 >= total_w - third) - { - in_x = images[image_number]->get_w() - - (total_w - x1); - in_w = total_w - x1; - } + if( pixel < right_pixel ) { + region = METER_MID; + in_start = region_pixel(region); + in_span = region_pixels(region); + } + else { + region = METER_RIGHT; + in_start = (pixel - right_pixel) + region_pixel(region); + in_span = region_pixels(region) - (in_start - region_pixel(region));; + } - int in_y = images[image_number]->get_h() - in_start - in_span; -//printf("BC_Meter::draw_face %d %d %d\n", __LINE__, get_w(), x + x1 + in_w, in_x, in_y, in_w, span); + //printf("BC_Meter::draw_face region %d pixel %d pixels %d in_start %d in_span %d\n", region, pixel, pixels, in_start, in_span); + if( in_span > 0 ) { + // Clip length to peaks + if( pixel < level_pixel && pixel + in_span > level_pixel ) + in_span = level_pixel - pixel; + else + if( pixel < peak_pixel1 && pixel + in_span > peak_pixel1 ) + in_span = peak_pixel1 - pixel; + else + if( pixel < peak_pixel2 && pixel + in_span > peak_pixel2 ) + in_span = peak_pixel2 - pixel; + // Clip length to color changes + if( image_number == METER_GREEN && pixel + in_span > low_division ) + in_span = low_division - pixel; + else + if( image_number == METER_YELLOW && pixel + in_span > medium_division ) + in_span = medium_division - pixel; + else + if( image_number == METER_RED && pixel + in_span > high_division ) + in_span = high_division - pixel; + // Clip length to regions + if( pixel < left_pixel && pixel + in_span > left_pixel ) + in_span = left_pixel - pixel; + else + if( pixel < right_pixel && pixel + in_span > right_pixel ) + in_span = right_pixel - pixel; + + //printf("BC_Meter::draw_face image_number %d pixel %d pixels %d in_start %d in_span %d\n", image_number, pixel, pixels, in_start, in_span); + //printf("BC_Meter::draw_face %d %d %d %d\n", orientation, region, images[image_number]->get_h() - in_start - in_span); + if( orientation == METER_HORIZ ) { + draw_pixmap(images[image_number], pixel, + x, in_span + 1, get_h(), in_start, 0); + } + else { + //printf("BC_Meter::draw_face %d %d\n", __LINE__, span); + if( span < 0 ) { draw_pixmap(images[image_number], - x + x1, get_h() - pixel - in_span, - in_w, in_span + 1, in_x, in_y); + x, get_h() - pixel - in_span, + get_w(), in_span + 1, 0, + images[image_number]->get_h() - in_start - in_span); + } + else { + int total_w = get_w() - x; + int third = images[image_number]->get_w() / 3 + 1; + + + for( int x1 = 0; x1 < total_w; x1 += third ) { + int in_x = 0; + int in_w = third; + if( x1 >= third ) in_x = third; + if( x1 >= total_w - third ) { + in_x = images[image_number]->get_w() - + (total_w - x1); + in_w = total_w - x1; + } + + int in_y = images[image_number]->get_h() - in_start - in_span; + //printf("BC_Meter::draw_face %d %d %d\n", __LINE__, get_w(), x + x1 + in_w, in_x, in_y, in_w, span); + + + draw_pixmap(images[image_number], + x + x1, get_h() - pixel - in_span, + in_w, in_span + 1, in_x, in_y); + } } } - } - pixel += in_span; - } - else - { -// Sanity check - break; + pixel += in_span; + } + else { + // Sanity check + break; + } } } - if(downmix) { - if(orientation == METER_HORIZ) + if( is_downmix ) { + if( orientation == METER_HORIZ ) draw_pixmap(images[METER_DOWNMIX], 0, 0); else - draw_pixmap(images[METER_DOWNMIX], x, - get_h() - images[METER_DOWNMIX]->get_h()-1); + draw_pixmap(images[METER_DOWNMIX], + x, get_h() - images[METER_DOWNMIX]->get_h() - 1); } - - if(over_timer) - { - if(orientation == METER_HORIZ) + if( over_timer ) { + if( orientation == METER_HORIZ ) draw_pixmap(images[METER_OVER], xS(20), yS(2)); else - draw_pixmap(images[METER_OVER], x, get_h() - yS(100)); + draw_pixmap(images[METER_OVER], + x + xS(2), get_h() - yS(100)); over_timer--; } - if(orientation == METER_HORIZ) + if( orientation == METER_HORIZ ) flash(0, 0, pixels, get_h(), flush); else flash(x, 0, w, pixels, flush); } -int BC_Meter::update(float new_value, int over, int dmix) +int BC_Meter::update(float new_value, int over, int downmix) { peak_timer++; - if(mode == METER_DB) - { - if(new_value == 0) + if( mode == METER_DB ) { + if( new_value == 0 ) level = min; else - level = db.todb(new_value); // db value + level = DB::todb(new_value); // db value } - if(level > peak || peak_timer > peak_delay) - { + + if( is_gain_change && fabs(level) > fabs(peak) || + !is_gain_change && level > peak || + peak_timer > peak_delay ) { peak = level; peak_timer = 0; } -// if(orientation == METER_HORIZ) +// if( orientation == METER_HORIZ ) // printf("BC_Meter::update %f\n", level); - if(over) over_timer = over_delay; + if( over ) over_timer = over_delay; // only draw if window is visible - if(dmix >= 0) downmix = dmix; - + if( downmix >= 0 ) + is_downmix = downmix; draw_face(1); return 0; }