* 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"
#include "bcpixmap.h"
#include "bcresources.h"
#include "bcwindow.h"
-#include "bccolors.h"
+#include "colors.h"
#include "fonts.h"
#include "vframe.h"
#include <string.h>
#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;
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();
}
{
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()
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
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());
return 0;
}
-int BC_Meter::reset(int dmix)
+int BC_Meter::reset(int downmix)
{
level = min;
peak = min;
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;
}
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;
}
db_titles.remove_all_objects();
title_pixels.remove_all();
tick_pixels.remove_all();
+ tick_w.remove_all();
low_division = 0;
medium_division = 0;
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;
+ (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() - 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() - 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);
}
}
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;
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;
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)
- draw_pixmap(images[METER_DOWNMIX],
- 0,
- 0);
+ 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);
+ x, get_h() - images[METER_DOWNMIX]->get_h() - 1);
}
-
- if(over_timer)
- {
- if(orientation == METER_HORIZ)
- draw_pixmap(images[METER_OVER],
- 20,
- 2);
+ 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() - 100);
+ 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;
}