//============================================================================== void MeterComponent::paint (Graphics& g) { //[UserPrePaint] Add your own custom painting code here.. //[/UserPrePaint] g.fillAll (Colours::white); g.setTiledImageFill (cachedImage_meter_gradient_off_png, 0, 0, 1.0000f); g.fillRect (0, 0, 8, 163); g.setTiledImageFill (cachedImage_meter_gradient_png, 0, 0, 1.0000f); // 163 max height int size_rms = (int)floorf(iec_scale(rms_db - _offset)*163.f); int y_rms = 163-size_rms; g.fillRect (0, y_rms, 8, size_rms); // peak value int y_dpk = (int)floorf(163 - iec_scale(dpk_db - _offset)*163.f); if (dpk_db > 0.f) g.setColour (Colours::red); else g.setColour (Colours::white); g.fillRect (0, y_dpk, 8, 2); if (_peak_hold) { // hold peak value int y_dpk_hold = (int)floorf(163 - iec_scale(dpk_hold_db - _offset)*163.f); if (y_dpk_hold < 0) { y_dpk_hold = 0; } if (dpk_hold_db > 0.f) { g.setColour (Colours::red); } else { g.setColour (Colours::yellow); } g.fillRect (0, y_dpk_hold, 8, 2); } // g.fillRect (0, 0, 8, 163); //[UserPaint] Add your own custom painting code here.. //[/UserPaint] }
void MeterWidget::paintEvent(QPaintEvent *) { QPainter painter(this); int max = this->graphicsDark->height() / (this->_blockSize + this->_spaceSize); int size = this->_blockSize + this->_spaceSize; int height = max * size; int split = iec_scale(20.0f * log10f(this->peak), max); painter.drawPixmap(0, 0, this->graphicsDark->copy(0, 0, this->graphicsDark->width(), this->graphicsDark->height() - split * size)); painter.drawPixmap(0, height - split * size, this->graphicsLight->copy(0, height - split * size, this->graphicsLight->width(), this->graphicsLight->height())); }
/***************************************************************************** * parse_i_values : parse i_values parameter and store the corresponding values *****************************************************************************/ static void parse_i_values(BarGraph_t *p_BarGraph, char *i_values) { char delim[] = ":"; char* tok; p_BarGraph->nbChannels = 0; free(p_BarGraph->i_values); p_BarGraph->i_values = NULL; char *res = strtok_r(i_values, delim, &tok); while (res != NULL) { p_BarGraph->nbChannels++; p_BarGraph->i_values = xrealloc(p_BarGraph->i_values, p_BarGraph->nbChannels*sizeof(int)); float db = log10(atof(res)) * 20; p_BarGraph->i_values[p_BarGraph->nbChannels-1] = VLC_CLIP(iec_scale(db)*p_BarGraph->scale, 0, p_BarGraph->scale); res = strtok_r(NULL, delim, &tok); } }
/** @internal @This handles data. * * @param upipe description structure of the pipe * @param uref uref structure describing the picture * @param upump_p reference to pump that generated the buffer * @return true if the packet was handled */ static bool upipe_audiobar_handle(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_audiobar *upipe_audiobar = upipe_audiobar_from_upipe(upipe); const char *def; if (unlikely(ubase_check(uref_flow_get_def(uref, &def)))) { UBASE_FATAL(upipe, uref_sound_flow_get_channels(uref, &upipe_audiobar->channels)) uref_sound_flow_clear_format(uref); UBASE_FATAL(upipe, uref_attr_import(uref, upipe_audiobar->flow_def_config)) uref_pic_flow_clear_format(uref); UBASE_FATAL(upipe, uref_pic_flow_set_planes(uref, 0)) UBASE_FATAL(upipe, uref_pic_flow_set_macropixel(uref, 1)) UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 1, 1, 1, "y8")) UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 2, 1, 1, "u8")) UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 2, 1, 1, "v8")) UBASE_FATAL(upipe, uref_pic_flow_add_plane(uref, 1, 1, 1, "a8")) UBASE_FATAL(upipe, uref_pic_set_progressive(uref)) upipe_audiobar->hsize = upipe_audiobar->vsize = upipe_audiobar->sep_width = upipe_audiobar->pad_width = UINT64_MAX; upipe_audiobar_require_flow_format(upipe, uref); return true; } if (!upipe_audiobar->ubuf_mgr) return false; if (unlikely(upipe_audiobar->hsize == UINT64_MAX)) return false; struct ubuf *ubuf = ubuf_pic_alloc(upipe_audiobar->ubuf_mgr, upipe_audiobar->hsize, upipe_audiobar->vsize); uref_attach_ubuf(uref, ubuf); uint8_t *dst[4]; size_t strides[4]; uint8_t hsubs[4]; uint8_t vsubs[4]; static const char *chroma[4] = { "y8", "u8", "v8", "a8" }; for (int i = 0; i < 4; i++) { if (unlikely(!ubase_check(uref_pic_plane_write(uref, chroma[i], 0, 0, -1, -1, &dst[i])) || !ubase_check(uref_pic_plane_size(uref, chroma[i], &strides[i], &hsubs[i], &vsubs[i], NULL)))) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); uref_free(uref); return true; } } uint8_t alpha = upipe_audiobar->alpha; uint64_t h = upipe_audiobar->vsize; const int hred = h - (iec_scale(-8.) * h); const int hyellow = h - (iec_scale(-18.) * h); uint8_t transparent[4] = { 0x10, 0x80, 0x80, 0 }; uint8_t black[4] = { 0x10, 0x80, 0x80, alpha }; uint8_t red[2][4] = { { 76, 85, 0xff, alpha }, { 37, 106, 191, alpha } }; uint8_t green[2][4] = { { 150, 44, 21, alpha }, { 74, 85, 74, alpha } }; uint8_t yellow[2][4] = { { 226, 1, 148, alpha }, { 112, 64, 138, alpha } }; uint64_t pts = 0; if (unlikely(!ubase_check(uref_clock_get_pts_prog(uref, &pts)))) { upipe_warn(upipe, "unable to read pts"); } for (uint8_t chan = 0; chan < upipe_audiobar->channels; chan++) { double amplitude = 0.; if (unlikely(!ubase_check(uref_amax_get_amplitude(uref, &litude, chan)))) upipe_warn_va(upipe, "unable to get amplitude for channel %"PRIu8", assuming silence", chan); double scale = log10(amplitude) * 20; // IEC-268-18 return time speed is 20dB per 1.7s (+/- .3) if (upipe_audiobar->peak_date[chan]) upipe_audiobar->peak[chan] -= 20 * (pts - upipe_audiobar->peak_date[chan]) / (1.7 * UCLOCK_FREQ); upipe_audiobar->peak_date[chan] = pts; if (scale >= upipe_audiobar->peak[chan]) /* higher than lowered peak */ upipe_audiobar->peak[chan] = scale; else /* Current amplitude can not go below the lowered peak value */ scale = upipe_audiobar->peak[chan]; scale = iec_scale(scale); const int hmax = h - scale * h; for (int row = 0; row < h; row++) { bool bright = row > hmax; const uint8_t *color = row < hred ? red[!bright] : row < hyellow ? yellow[!bright] : green[!bright]; copy_color(dst, strides, hsubs, vsubs, color, row, chan * upipe_audiobar->chan_width, upipe_audiobar->chan_width); if (chan && upipe_audiobar->sep_width) copy_color(dst, strides, hsubs, vsubs, black, row, chan * upipe_audiobar->chan_width - upipe_audiobar->sep_width / 2, upipe_audiobar->sep_width); if (chan == upipe_audiobar->channels - 1 && upipe_audiobar->pad_width) copy_color(dst, strides, hsubs, vsubs, transparent, row, (chan + 1) * upipe_audiobar->chan_width, upipe_audiobar->pad_width); } } /* dB marks */ for (int i = 1; i <= 6; i++) { int row = h - (iec_scale(-10 * i) * h); copy_color(dst, strides, hsubs, vsubs, black, row, 0, upipe_audiobar->hsize); } for (int i = 0; i < 4; i++) ubuf_pic_plane_unmap(ubuf, chroma[i], 0, 0, -1, -1); upipe_audiobar_output(upipe, uref, upump_p); return true; }
/***************************************************************************** * Draw: creates and returns the bar graph image *****************************************************************************/ static void Draw(BarGraph_t *b) { int nbChannels = b->nbChannels; int scale = b->scale; int barWidth = b->barWidth; int w = 40; if (nbChannels > 0) w = 2 * nbChannels * barWidth + 30; int h = scale + 30; int level[6]; for (int i = 0; i < 6; i++) level[i] = iec_scale(-(i+1) * 10) * scale + 20; if (b->p_pic) picture_Release(b->p_pic); b->p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), w, h, 1, 1); if (!b->p_pic) return; picture_t *p_pic = b->p_pic; plane_t *p = p_pic->p; for (int i = 0 ; i < p_pic->i_planes ; i++) memset(p[i].p_pixels, 0x00, p[i].i_visible_lines * p[i].i_pitch); Draw2VLines(p, scale, 20, black); Draw2VLines(p, scale, 22, white); static const uint8_t pixmap[6][5] = { { 0x17, 0x15, 0x15, 0x15, 0x17 }, { 0x77, 0x45, 0x75, 0x15, 0x77 }, { 0x77, 0x15, 0x75, 0x15, 0x77 }, { 0x17, 0x15, 0x75, 0x55, 0x57 }, { 0x77, 0x15, 0x75, 0x45, 0x77 }, { 0x77, 0x55, 0x75, 0x45, 0x77 }, }; for (int i = 0; i < 6; i++) { DrawHLines(p, h - 1 - level[i] - 1, 24, white, 1, 3); DrawHLines(p, h - 1 - level[i], 24, black, 2, 3); DrawNumber(p, h, pixmap[i], level[i]); } int minus8 = iec_scale(- 8) * scale + 20; int minus18 = iec_scale(-18) * scale + 20; int *i_values = b->i_values; const uint8_t *indicator_color = b->alarm ? bright_red : black; for (int i = 0; i < nbChannels; i++) { int pi = 30 + i * (5 + barWidth); DrawHLines(p, h - 20 - 1, pi, indicator_color, 8, barWidth); for (int line = 20; line < i_values[i] + 20; line++) { if (line < minus18) DrawHLines(p, h - line - 1, pi, bright_green, 1, barWidth); else if (line < minus8) DrawHLines(p, h - line - 1, pi, bright_yellow, 1, barWidth); else DrawHLines(p, h - line - 1, pi, bright_red, 1, barWidth); } for (int line = i_values[i] + 20; line < scale + 20; line++) { if (line < minus18) DrawHLines(p, h - line - 1, pi, green, 1, barWidth); else if (line < minus8) DrawHLines(p, h - line - 1, pi, yellow, 1, barWidth); else DrawHLines(p, h - line - 1, pi, red, 1, barWidth); } } }
/***************************************************************************** * LoadImage: creates and returns the bar graph image *****************************************************************************/ static picture_t *LoadImage( vlc_object_t *p_this, int nbChannels, int* i_values, int scale, int alarm, int barWidth) { VLC_UNUSED(p_this); picture_t *p_pic; int i, j, pi; int i_width = 0; int i_line; int minus8, minus10, minus18, minus20, minus30, minus40, minus50, minus60; if (nbChannels == 0) { i_width = 20; } else { i_width = 2 * nbChannels * barWidth + 10; } minus8 = iec_scale(-8)*scale + 20; minus10 = iec_scale(-10)*scale + 20; minus18 = iec_scale(-18)*scale + 20; minus20 = iec_scale(-20)*scale + 20; minus30 = iec_scale(-30)*scale + 20; minus40 = iec_scale(-40)*scale + 20; minus50 = iec_scale(-50)*scale + 20; minus60 = iec_scale(-60)*scale + 20; p_pic = picture_New(VLC_FOURCC('Y','U','V','A'), i_width+20, scale+30, 1, 1); #define DrawLine(a,b,Y,U,V,A) \ for (i=a; i<b; i++) {\ *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + i ) = Y;\ *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + i ) = U;\ *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + i ) = V;\ *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + i ) = A; \ } #define DrawLineBlack(a,b) DrawLine(a,b,0,128,128,0xFF) #define DrawLineWhite(a,b) DrawLine(a,b,255,128,128,0xFF) // blacken the whole picture for( i = 0 ; i < p_pic->i_planes ; i++ ) { memset( p_pic->p[i].p_pixels, 0x00, p_pic->p[i].i_visible_lines * p_pic->p[i].i_pitch ); } // side bar for ( i_line = 20; i_line < scale+20; i_line++ ) { // vertical line DrawLineBlack(20,22); DrawLineWhite(22,24); // -10dB if (i_line == minus10 - 2) { // 1 DrawLineBlack(14,15); // 0 DrawLineBlack(16,19); } if (i_line == minus10 - 1) { // 1 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineWhite(24,27); //White } if (i_line == minus10) { // 1 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus10 + 1) { // 1 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus10 + 2) { // 1 DrawLineBlack(14,15); // 0 DrawLineBlack(16,19); } // -20dB if (i_line == minus20 - 2) { // 2 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } if (i_line == minus20 - 1) { // 2 DrawLineBlack(12,13); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineWhite(24,27); //White } if (i_line == minus20) { // 2 DrawLineBlack(12,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus20 + 1) { // 2 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus20 + 2) { // 2 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } // -30dB if (i_line == minus30 - 2) { // 3 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } if (i_line == minus30 - 1) { // 3 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineWhite(24,27); //White } if (i_line == minus30) { // 3 DrawLineBlack(12,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus30 + 1) { // 3 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus30 + 2) { // 3 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } // -40dB if (i_line == minus40 - 2) { // 4 DrawLineBlack(14,15); // 0 DrawLineBlack(16,19); } if (i_line == minus40 - 1) { // 4 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineWhite(24,27); // white } if (i_line == minus40) { // 4 DrawLineBlack(12,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus40 + 1) { // 4 DrawLineBlack(12,13); DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus40 + 2) { // 4 DrawLineBlack(12,13); DrawLineBlack(14,15); // 0 DrawLineBlack(16,19); } // -50dB if (i_line == minus50 - 2) { // 5 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } if (i_line == minus50 - 1) { // 5 DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineWhite(24,27); //White } if (i_line == minus50) { // 5 DrawLineBlack(12,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus50 + 1) { // 5 DrawLineBlack(12,13); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus50 + 2) { // 2 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } // -60dB if (i_line == minus60 - 2) { // 6 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } if (i_line == minus60 - 1) { // 6 DrawLineBlack(12,13); DrawLineBlack(14,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineWhite(24,27); //White } if (i_line == minus60) { // 6 DrawLineBlack(12,15); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus60 + 1) { // 6 DrawLineBlack(12,13); // 0 DrawLineBlack(16,17); DrawLineBlack(18,19); // limit DrawLineBlack(24,27); } if (i_line == minus60 + 2) { // 6 DrawLineBlack(12,15); // 0 DrawLineBlack(16,19); } } #define drawPoint(offset,y,u,v,a) \ *(p_pic->p[0].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[0].i_pitch + offset ) = y; \ *(p_pic->p[1].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[1].i_pitch + offset ) = u; \ *(p_pic->p[2].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[2].i_pitch + offset ) = v; \ *(p_pic->p[3].p_pixels + (scale + 30 - i_line - 1) * p_pic->p[3].i_pitch + offset ) = a; // draw the bars and channel indicators for (i=0; i<nbChannels; i++) { pi = 25 + ((i+1)*5) + (i*barWidth) ; // 25 separació amb indicador, 5 separació entre barres for( j = pi; j < pi + barWidth; j++) { // channel indicators for ( i_line = 12; i_line < 20; i_line++ ) { if( alarm ) { drawPoint(j,76,85,0xFF,0xFF); // red } else { drawPoint(j,0,128,128,0xFF); // black DrawLine(pi,pf,0xFF,128,128,0xFF); } } // bars for( i_line = 20; i_line < i_values[i]+20; i_line++ ) { if (i_line < minus18) { // green if < -18 dB drawPoint(j,150,44,21,0xFF); //DrawLine(pi,pf,150,44,21,0xFF); } else if (i_line < minus8) { // yellow if > -18dB and < -8dB drawPoint(j,226,1,148,0xFF); //DrawLine(pi,pf,226,1,148,0xFF); } else { // red if > -8 dB drawPoint(j,76,85,0xFF,0xFF); //DrawLine(pi,pf,76,85,255,0xFF); } } // bars no signal for( ; i_line < scale+20; i_line++ ) { if (i_line < minus18) { // green if < -18 dB drawPoint(j,74,85,74,0xFF); //DrawLine(pi,pf,74,85,74,0xFF); } else if (i_line < minus8) { // yellow if > -18dB and < -8dB drawPoint(j,112,64,138,0xFF); //DrawLine(pi,pf,112,64,138,0xFF); } else { // red if > -8 dB drawPoint(j,37,106,191,0xFF); //DrawLine(pi,pf,37,106,191,0xFF); } } } } return p_pic; }
int peak_db(float peak, float bias, float mult) { return (int) (iec_scale(20.0f * log10f(peak * bias)) * mult); }