Пример #1
2
static void plot_data_fft(SFSUI* ui) {
	cairo_t* cr;
	cr = cairo_create (ui->sf_dat);

	rounded_rectangle (cr, SS_BORDER, SS_BORDER, SS_SIZE, SS_SIZE, SS_BORDER);
	cairo_clip_preserve (cr);

	const float persistence = robtk_dial_get_value(ui->screen);
	float transp;
	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
	if (persistence > 0) {
		cairo_set_source_rgba(cr, 0, 0, 0, .25 - .0025 * persistence);
		transp = 0.05;
	} else {
		cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
		transp = .5;
	}
	cairo_fill(cr);

	cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
	cairo_set_line_width (cr, 1.0);

	const float xmid = rintf(SS_BORDER + SS_SIZE *.5) + .5;
	const float dnum = SS_SIZE / ui->log_base;
	const float denom = ui->log_rate / (float)ui->fft_bins;

	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
	for (uint32_t i = 1; i < ui->fft_bins-1 ; ++i) {
		if (ui->level[i] < 0) continue;

		const float level = MAKEUP_GAIN + fftx_power_to_dB(ui->level[i]);
		if (level < -80) continue;

		const float y  = rintf(SS_BORDER + SS_SIZE - dnum * fast_log10(1.0 + i * denom)) + .5;
		const float y1 = rintf(SS_BORDER + SS_SIZE - dnum * fast_log10(1.0 + (i+1) * denom)) + .5;
		const float pk = level > 0.0 ? 1.0 : (80 + level) / 80.0;
		const float a_lr = ui->lr[i];

		float clr[3];
		hsl2rgb(clr, .70 - .72 * pk, .9, .3 + pk * .4);
		cairo_set_source_rgba(cr, clr[0], clr[1], clr[2], transp  + pk * .2);
		cairo_set_line_width (cr, MAX(1.0, (y - y1)));

		cairo_move_to(cr, xmid, y);
		cairo_line_to(cr, SS_BORDER + SS_SIZE * a_lr, y);
		cairo_stroke(cr);

	}
	cairo_destroy (cr);
}
Пример #2
1
void TrackEffects::populateAuxForTrack(AudioTrack* t)/*{{{*/
{
	if (t && t->hasAuxSend())
	{
		AuxProxy *proxy = new AuxProxy(t);
		int idx = 0;
		QHash<qint64, AuxInfo>::const_iterator iter = t->auxSends()->constBegin();
		while (iter != t->auxSends()->constEnd())
		{
			Track* at = song->findTrackByIdAndType(iter.key(), Track::AUDIO_AUX);
			if(at)
			{
				//qDebug("Adding AUX to strip: Name: %s, tid: %lld, auxId: %lld", at->name().toUtf8().constData(), at->id(), iter.key());
				DoubleLabel* al;
				QLabel* nl;
				Knob* ak = addAuxKnob(proxy, iter.key(), at->name(), &al, &nl);
				proxy->auxIndexList[idx] = iter.key();
				proxy->auxKnobList[iter.key()] = ak;
				proxy->auxLabelList[iter.key()] = al;
				proxy->auxNameLabelList[iter.key()] = nl;
				ak->setId(idx);
				al->setId(idx);
				double val = fast_log10(t->auxSend(iter.key()))*20.0;
				ak->setValue(val);
				al->setValue(val);
				++idx;
			}
			++iter;
		}
		m_proxy.insert(t->id(), proxy);
	}
}/*}}}*/
Пример #3
1
void AbstractSlider::setMaxLogValue(double val)
      {
      if (_log) {
            _maxValue = fast_log10(val) * 20.0f;
            }
      else
            _maxValue = val;
      }
Пример #4
1
void AbstractSlider::setMinLogValue(double val)
      {
      if (_log) {
            if (val == 0.0f)
                  _minValue = -100;
            else
                  _minValue = fast_log10(val) * 20.0f;
            }
      else
            _minValue = val;
      }
Пример #5
0
	void FloatEntry::setValue(double val)
	{
		if (_log)
		{
			if (val == 0.0f)
				_value = _minValue;
			else
				_value = fast_log10(val) * 20.0f;
		}
		else
			_value = val;
		updateValue();
	}
Пример #6
0
static void process_audio(SFSUI* ui, const size_t n_elem, float const * const left, float const * const right) {
	pthread_mutex_lock(&ui->fft_lock);

	fftx_run(ui->fa, n_elem, left);
	bool display = !fftx_run(ui->fb, n_elem, right);

	if (display) {
		assert (fftx_bins(ui->fa) == ui->fft_bins);
		const float db_thresh = 1e-20;

		for (uint32_t i = 1; i < ui->fft_bins-1; i++) {
			if (ui->fa->power[i] < db_thresh && ui->fb->power[i] < db_thresh) {
				ui->lr[i] = 0.5;
				ui->level[i] = 0;
				continue;
			}
			const float lv = MAX(ui->fa->power[i], ui->fb->power[i]);
#if 1
			const float lr = .5 + .5 * (sqrtf(ui->fb->power[i]) - sqrtf(ui->fa->power[i])) / sqrtf(lv);
#else
			//XXX TODO log-scale / deflection of fraction
			//const float lr = .5 + .25 * fast_log10(ui->fb->power[i] / ui->fa->power[i]);
			float lr;
			if (ui->fb->power[i] < ui->fa->power[i]) {
				lr = .5 + .5 * fast_log10(ui->fb->power[i] / ui->fa->power[i]);
			} else {
				lr = .5 - .5 * fast_log10(ui->fa->power[i] / ui->fb->power[i]);
			}
#endif

			ui->level[i] += .1 * (lv - ui->level[i]) + 1e-20;
			ui->lr[i] += .1 * (lr - ui->lr[i]) + 1e-10;
		}
		queue_draw(ui->m0);
	}
	pthread_mutex_unlock(&ui->fft_lock);
}
Пример #7
0
void AbstractSlider::setValue(double val)
      {
      if (_log) {
            if (val == 0.0f)
                  _value = _minValue;
            else {
                  _value = fast_log10(val) * 20.0f;
                  if (_value < _minValue)
                        _value = _minValue;
                  }
            }
      else
            _value = val;
      update();
      }
Пример #8
0
/* linear FFT data display */
static void plot_data_fft(MF2UI* ui) {
	cairo_t* cr;
	const double ccc = ui->width / 2.0 + .5;
	const double rad = (ui->width - XOFF) * .5;
	const float gain = robtk_dial_get_value(ui->gain);
	const float persistence = robtk_dial_get_value(ui->screen);

	cr = cairo_create (ui->sf_dat);
	cairo_arc (cr, ccc, ccc, rad, 0, 2.0 * M_PI);
	cairo_clip_preserve (cr);

	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
	if (persistence > 0) {
		cairo_set_source_rgba(cr, 0, 0, 0, .3 - .003 * persistence);
	} else {
		cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
	}
	cairo_fill(cr);
	cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
	const float dnum = ui->scale * PH_RAD / ui->log_base;
	const float denom = ui->log_rate / (float)ui->fft_bins;
	const float cutoff = ui->db_cutoff;
	for (uint32_t i = 1; i < ui->fft_bins-1 ; ++i) {
		if (ui->level[i] < 0) continue;
		const float level = gain + fftx_power_to_dB(ui->level[i]);
		if (level < cutoff) continue;

		const float dist = dnum * fast_log10(1.0 + i * denom);
		const float dx = ccc + dist * sinf(ui->phase[i]);
		const float dy = ccc - dist * cosf(ui->phase[i]);
		const float pk = level > 0.0 ? 1.0 : (cutoff - level) / cutoff;

		draw_point(ui, cr, pk, dx, dy, ccc, dist, ui->phase[i]);
	}
	cairo_destroy (cr);
}
Пример #9
0
 inline decibel::decibel(double val)
  : val(20.0f * fast_log10(val))
 {}
Пример #10
0
double trackVolToDb(double vol)
{
	return fast_log10(vol) * 20.0;
}
Пример #11
0
static void plot_data_oct(SFSUI* ui) {
	cairo_t* cr;
	cr = cairo_create (ui->sf_dat);
	rounded_rectangle (cr, SS_BORDER, SS_BORDER, SS_SIZE, SS_SIZE, SS_BORDER);
	cairo_clip_preserve (cr);

	const float persistence = robtk_dial_get_value(ui->screen);
	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
	if (persistence > 0) {
		cairo_set_source_rgba(cr, 0, 0, 0, .33 - .0033 * persistence);
	} else {
		cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
	}
	cairo_fill(cr);
	cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);

	const float xmid = rintf(SS_BORDER + SS_SIZE *.5) + .5;
	const float dnum = SS_SIZE / ui->log_base;
	const float denom = 2.0 * ui->log_rate / ui->rate;

	uint32_t fi = 1;
	for (uint32_t i = 0; i < ui->freq_bins; ++i) {
		float a_lr = 0;
		float a_level = 0;
		float a_freq = 0;
		uint32_t a_cnt = 0;

		while(fi < ui->freq_band[i]) {
			if (ui->level[fi] < 0) { fi++; continue; }

			a_freq += fi * ui->fa->freq_per_bin;
			a_level += ui->level[fi];
			a_lr += ui->lr[fi];
			a_cnt++;
			fi++;
		}
		if (a_cnt == 0) continue;
		a_level = MAKEUP_GAIN + fftx_power_to_dB (a_level);
		if (a_level < -80) continue;

		a_freq /= (float)a_cnt;
		a_lr /= (float)a_cnt;

		const float y = rintf(SS_BORDER + SS_SIZE - dnum * fast_log10(1.0 + a_freq * denom)) + .5;
		const float pk = a_level > 0.0 ? 1.0 : (80 + a_level) / 80.0;

		float clr[3];
		hsl2rgb(clr, .70 - .72 * pk, .9, .3 + pk * .4);
		cairo_set_source_rgba(cr, clr[0], clr[1], clr[2], 0.8);

		if (fabsf(a_lr -.5) < .05) {
			cairo_set_line_width (cr, 3.0);
		} else {
			cairo_set_line_width (cr, 1.0);
		}

		cairo_move_to(cr, xmid, y);
		cairo_line_to(cr, SS_BORDER + SS_SIZE * a_lr, y);
		cairo_stroke(cr);
	}
	cairo_destroy (cr);
}
Пример #12
0
void Mixer_Strip::set_rms_level(int _index, float _rms_level)
{
  rms_level_n_1[_index] = rms_level[_index];
  rms_level[_index] = att_rms_level * rms_level_n_1[_index] + (1.0 - att_rms_level) * fast_log10(_rms_level);
  if (rms_level[_index]>DB_VOL_MAX) rms_level[_index] = DB_VOL_MAX;
  if (rms_level[_index]<DB_VOL_MIN) rms_level[_index] = DB_VOL_MIN;
  coarseDial->setMeterVal(_index, rms_level[_index], max_level[_index]);
}
Пример #13
0
/* 1/Octave data display */
static void plot_data_oct(MF2UI* ui) {
	cairo_t* cr;
	const double ccc = ui->width / 2.0 + .5;
	const double rad = (ui->width - XOFF) * .5;
	const float gain = robtk_dial_get_value(ui->gain);
	const float persistence = robtk_dial_get_value(ui->screen);

	cr = cairo_create (ui->sf_dat);
	cairo_arc (cr, ccc, ccc, rad, 0, 2.0 * M_PI);
	cairo_clip_preserve (cr);

	cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
	if (persistence > 0) {
		cairo_set_source_rgba(cr, 0, 0, 0, .33 - .0033 * persistence);
	} else {
		cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
	}
	cairo_fill(cr);
	cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);

	const float dnum = ui->scale * PH_RAD / ui->log_base;
	const float denom = 2.0 * ui->log_rate / ui->rate;
	const float cutoff = ui->db_cutoff;

	uint32_t fi = 1;
	for (uint32_t i = 0; i < ui->freq_bins; ++i) {
		float ang_x = 0;
		float ang_y = 0;
		float a_level = 0;
		float a_freq = 0;
		uint32_t a_cnt = 0;

		while(fi < ui->freq_band[i]) {
			if (ui->level[fi] < 0) { fi++; continue; }
			a_freq += fi * ui->fa->freq_per_bin;
			a_level += ui->level[fi];
			ang_x += sinf(ui->phase[fi]);
			ang_y += cosf(ui->phase[fi]);
			a_cnt++;
			fi++;
		}
		if (a_cnt == 0) continue;
		a_level = gain + fftx_power_to_dB (a_level);
		if (a_level < cutoff) continue;

		a_freq /= (float)a_cnt;
		const float dist = dnum * fast_log10(1.0 + a_freq * denom);
		const float pk = a_level > 0.0 ? 1.0 : (cutoff - a_level) / cutoff;

		float dx, dy;
		if (a_cnt == 1) {
			dx = ccc + dist * ang_x;
			dy = ccc - dist * ang_y;
		} else {
			const float phase = atan2f(ang_x, ang_y);
			dx = ccc + dist * sinf(phase);
			dy = ccc - dist * cosf(phase);
		}

		draw_point(ui, cr, pk, dx, dy, 0, 0, 0);
	}

	cairo_destroy (cr);
}
Пример #14
0
/** draw frequency calibration circles
 * and on screen annotations - sample-rate dependent
 */
static void update_grid(MF2UI* ui) {
	const double ccc = ui->width / 2.0 + .5;
	const double rad = (ui->width - XOFF) * .5;
	cairo_t *cr = cairo_create (ui->sf_ann);

	cairo_rectangle (cr, 0, 0, ui->width, ui->height);
	CairoSetSouerceRGBA(ui->c_bg);
	cairo_fill (cr);

	cairo_set_line_width (cr, 1.0);

	cairo_arc (cr, ccc, ccc, rad, 0, 2.0 * M_PI);
	cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
	cairo_fill_preserve(cr);
	CairoSetSouerceRGBA(c_g90);
	cairo_stroke(cr);

	const double dash1[] = {1.0, 2.0};
	cairo_set_dash(cr, dash1, 2, 0);

	CairoSetSouerceRGBA(c_grd);

	float freq = 62.5;
	while (freq < ui->rate / 2) {
		char txt[16];
		if (freq < 1000) {
			snprintf(txt, 16, "%d Hz", (int)ceil(freq));
		} else {
			snprintf(txt, 16, "%d KHz", (int)ceil(freq/1000.f));
		}

		{
			const float dr = ui->scale * PH_RAD * fast_log10(1.0 + 2 * freq * ui->log_rate / ui->rate) / ui->log_base;
			cairo_arc (cr, ccc, ccc, dr, 0, 2.0 * M_PI);
			cairo_stroke(cr);
			const float px = ccc + dr * sinf(M_PI * -.75);
			const float py = ccc - dr * cosf(M_PI * -.75);
			write_text_full(cr, txt, ui->font[0], px, py, M_PI * -.75, -2, c_ahz);
		}

		freq *= 2.0;
	}

	const double dash2[] = {1.0, 3.0};
	cairo_set_line_width(cr, 3.5);
	cairo_set_dash(cr, dash2, 2, 2);

	cairo_set_line_width(cr, 1.5);
	cairo_move_to(cr, ccc - rad, ccc);
	cairo_line_to(cr, ccc + rad, ccc);
	cairo_stroke(cr);

	cairo_set_line_width(cr, 3.5);
	cairo_move_to(cr, ccc, ccc - rad);
	cairo_line_to(cr, ccc, ccc + rad);
	cairo_stroke(cr);
	cairo_set_dash(cr, NULL, 0, 0);

	write_text_full(cr, "+L",  ui->font[0], ccc, ccc - rad * .92, 0, -2, c_ann);
	write_text_full(cr, "-L",  ui->font[0], ccc, ccc + rad * .92, 0, -2, c_ann);
	write_text_full(cr, "0\u00B0",  ui->font[0], ccc, ccc - rad * .80, 0, -2, c_ann);
	write_text_full(cr, "180\u00B0",  ui->font[0], ccc, ccc + rad * .80, 0, -2, c_ann);

	write_text_full(cr, "-R",  ui->font[0], ccc - rad * .92, ccc, 0, -2, c_ann);
	write_text_full(cr, "+R",  ui->font[0], ccc + rad * .92, ccc, 0, -2, c_ann);
	write_text_full(cr, "-90\u00B0",  ui->font[0], ccc - rad * .80, ccc, 0, -2, c_ann);
	write_text_full(cr, "+90\u00B0",  ui->font[0], ccc + rad * .80, ccc, 0, -2, c_ann);
	cairo_destroy (cr);
}
Пример #15
0
FFTX_FN_PREFIX
inline float fftx_power_to_dB(float a) {
	/* 10 instead of 20 because of squared signal -- no sqrt(powerp[]) */
	return a > 1e-12 ? 10.0 * fast_log10(a) : -INFINITY;
}
Пример #16
0
void MeterSlider::paintEvent(QPaintEvent* ev)
      {
      int h  = height();
      int kh = sliderSize().height();
      int mh = h - kh;

      double range = maxValue() - minValue();
      int ppos     = int(mh * (_value - minValue()) / range);
      if (_invert)
            ppos = mh - ppos;

      QPainter p(this);
      p.setRenderHint(QPainter::Antialiasing, false);

      //---------------------------------------------------
      //    draw meter
      //---------------------------------------------------

      int mw = _meterWidth / _channel;
      int x  = 20;
      int y1 = kh / 2;
      int y3 = h - y1;

      p.setPen(QPen(Qt::white, 2));

      for (int i = 0; i < _channel; ++i) {
            int h = mh - (lrint(fast_log10(meterval[i]) * -20.0f * mh / range));
            if (h < 0)
                  h = 0;
            else if (h > mh)
                  h = mh;

	      p.drawPixmap(x, y1+mh-h, mw, h,    onPm,  0, mh-h, mw, h);
	      p.drawPixmap(x, y1,      mw, mh-h, offPm, 0, 0,    mw, mh-h);

            //---------------------------------------------------
            //    draw peak line
            //---------------------------------------------------

            h = mh - (lrint(fast_log10(meterPeak[i]) * -20.0f * mh / range));
            if (h > mh)
                  h = mh;
	      if (h > 0)
	            p.drawLine(x, y3-h, x+mw, y3-h);

            x += mw;
            }

      // optimize common case:
      if (ev->rect() == QRect(20, kh/2, _meterWidth-1, mh))
            return;

      QColor sc(isEnabled() ? _scaleColor : Qt::gray);
      QColor svc(isEnabled() ? _scaleValueColor : Qt::gray);
      p.setBrush(svc);

      //---------------------------------------------------
      //    draw scale
      //---------------------------------------------------

      int y2 = h - (ppos + y1);
      p.fillRect(x, y1, _scaleWidth, y2-y1, sc);
      p.fillRect(x, y2, _scaleWidth, y3-y2, svc);

      //---------------------------------------------------
      //    draw tick marks
      //---------------------------------------------------

  	QFont f(p.font());
   	f.setPointSize(6);
   	p.setFont(f);
      p.setPen(QPen(Qt::darkGray, 2));
   	QFontMetrics fm(f);
      int xt = 20 - fm.width("00") - 5;

      QString s;
   	for (int i = 10; i < 70; i += 10) {
      	h  = y1 + lrint(i * mh / range);
         	s.setNum(i - 10);
  		p.drawText(xt,  h - 3, s);
		p.drawLine(15, h, 20, h);
         	}

      //---------------------------------------------------
      //    draw slider
      //---------------------------------------------------

      x  += _scaleWidth/2;
      p.setPen(QPen(svc, 0));
      p.translate(QPointF(x, y2));
      p.setRenderHint(QPainter::Antialiasing, true);
      p.drawPath(*points);
      }
Пример #17
0
double CtrlList::value(int frame, bool cur_val_only, int* nextFrame) const
{
      if(cur_val_only || empty()) 
      {
        if(nextFrame)
          *nextFrame = -1;
        return _curVal;
      }

      double rv;
      int nframe;

      ciCtrl i = upper_bound(frame); // get the index after current frame
      if (i == end()) { // if we are past all items just return the last value
            --i;
            if(nextFrame)
              *nextFrame = -1;
            return i->second.val;
            }
      else if(_mode == DISCRETE)
      {
        if(i == begin())
        {
            nframe = i->second.frame;
            rv = i->second.val;
        }  
        else
        {  
          nframe = i->second.frame;
          --i;
          rv = i->second.val;
        }  
      }
      else {                  // INTERPOLATE
        if (i == begin()) {
            nframe = i->second.frame;
            rv = i->second.val;
        }
        else {
            int frame2 = i->second.frame;
            double val2 = i->second.val;
            --i;
            int frame1 = i->second.frame;
            double val1   = i->second.val;

            
            if(val2 != val1)
              nframe = 0; // Zero signifies the next frame should be determined by caller.
            else
              nframe = frame2;
            
            if (_valueType == VAL_LOG) {
              val1 = 20.0*fast_log10(val1);
              if (val1 < MusEGlobal::config.minSlider)
                val1=MusEGlobal::config.minSlider;
              val2 = 20.0*fast_log10(val2);
              if (val2 < MusEGlobal::config.minSlider)
                val2=MusEGlobal::config.minSlider;
            }

            val2  -= val1;
            val1 += (double(frame - frame1) * val2)/double(frame2 - frame1);
    
            if (_valueType == VAL_LOG) {
              val1 = exp10(val1/20.0);
            }

            rv = val1;
          }
      }

      if(nextFrame)
          *nextFrame = nframe;
      
      return rv;
}
Пример #18
0
void MidiVolEntry::setValue(double v)
      {
      FloatEntry::setValue(-fast_log10(double(_max*_max)/(v*v))*20.0f);
      }