예제 #1
0
int gWaveform::alloc(int datasize) {

	ratio = chan->wave->size / (float) datasize;

	if (ratio < 2)
		return 0;

	freeData();

	data.size = datasize;
	data.sup  = (int*) malloc(data.size * sizeof(int));
	data.inf  = (int*) malloc(data.size * sizeof(int));

	int offset = h() / 2;
	int zero   = y() + offset; // center, zero amplitude (-inf dB)


	for (int i=0; i<data.size; i++) {

		int pp;  // point prev
		int pn;  // point next

		/* resampling the waveform, hardcore way. Many thanks to
		 * http://fourier.eng.hmc.edu/e161/lectures/resize/node3.html
		 * Note: we use
		 * 	 p = j * (m-1 / n)
		 * instead of
		 * 	 p = j * (m-1 / n-1)
		 * in order to obtain 'datasize' cells to parse (and not datasize-1) */

		pp = i * ((chan->wave->size - 1) / (float) datasize);
		pn = (i+1) * ((chan->wave->size - 1) / (float) datasize);

		if (pp % 2 != 0) pp -= 1;
		if (pn % 2 != 0) pn -= 1;

		float peaksup = 0.0f;
		float peakinf = 0.0f;

		int k = pp;
		while (k < pn) {
			if (chan->wave->data[k] > peaksup)
				peaksup = chan->wave->data[k];    // Left data only
			else
			if (chan->wave->data[k] <= peakinf)
				peakinf = chan->wave->data[k];    // Left data only
			k += 2;
		}

		data.sup[i] = zero - (peaksup * chan->boost * offset);
		data.inf[i] = zero - (peakinf * chan->boost * offset);

		// avoid window overflow

		if (data.sup[i] < y())       data.sup[i] = y();
		if (data.inf[i] > y()+h()-1) data.inf[i] = y()+h()-1;
	}
	recalcPoints();
	return 1;
}
예제 #2
0
void gWaveform::openEditMenu() {

	if (selectionA == selectionB)
		return;

	menuOpen = true;

	Fl_Menu_Item menu[] = {
		{"Cut"},
		{"Trim"},
		{"Silence"},
		{"Fade in"},
		{"Fade out"},
		{"Smooth edges"},
		{"Set start/end here"},
		{0}
	};

	if (chan->status == STATUS_PLAY) {
		menu[0].deactivate();
		menu[1].deactivate();
	}

	Fl_Menu_Button *b = new Fl_Menu_Button(0, 0, 100, 50);
	b->box(G_BOX);
	b->textsize(11);
	b->textcolor(COLOR_TEXT_0);
	b->color(COLOR_BG_0);

	const Fl_Menu_Item *m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, b);
	if (!m) {
		menuOpen = false;
		return;
	}

	/* straightSel() to ensure that point A is always lower than B */

	straightSel();

	if (strcmp(m->label(), "Silence") == 0) {
		wfx_silence(chan->wave, absolutePoint(selectionA), absolutePoint(selectionB));

		selectionA = 0;
		selectionB = 0;

		stretchToWindow();
		redraw();
		menuOpen = false;
		return;
	}

	if (strcmp(m->label(), "Set start/end here") == 0) {

		glue_setBeginEndChannel(
				(gdEditor *) window(), // parent
				chan,
				absolutePoint(selectionA) * 2,  // stereo!
				absolutePoint(selectionB) * 2,  // stereo!
				false, // no recalc (we do it here)
				false  // don't check
				);

		selectionA     = 0;
		selectionB     = 0;
		selectionA_abs = 0;
		selectionB_abs = 0;

		recalcPoints();
		redraw();
		menuOpen = false;
		return;
	}

	if (strcmp(m->label(), "Cut") == 0) {
		wfx_cut(chan->wave, absolutePoint(selectionA), absolutePoint(selectionB));

		/* for convenience reset start/end points */

		glue_setBeginEndChannel(
			(gdEditor *) window(),
			chan,
			0,
			chan->wave->size,
			false);

		selectionA     = 0;
		selectionB     = 0;
		selectionA_abs = 0;
		selectionB_abs = 0;

		setZoom(0);

		menuOpen = false;
		return;
	}

	if (strcmp(m->label(), "Trim") == 0) {
		wfx_trim(chan->wave, absolutePoint(selectionA), absolutePoint(selectionB));

		glue_setBeginEndChannel(
			(gdEditor *) window(),
			chan,
			0,
			chan->wave->size,
			false);

		selectionA     = 0;
		selectionB     = 0;
		selectionA_abs = 0;
		selectionB_abs = 0;

		stretchToWindow();
		menuOpen = false;
		redraw();
		return;
	}

	if (!strcmp(m->label(), "Fade in") || !strcmp(m->label(), "Fade out")) {

		int type = !strcmp(m->label(), "Fade in") ? 0 : 1;
		wfx_fade(chan->wave, absolutePoint(selectionA), absolutePoint(selectionB), type);

		selectionA = 0;
		selectionB = 0;

		stretchToWindow();
		redraw();
		menuOpen = false;
		return;
	}

	if (!strcmp(m->label(), "Smooth edges")) {

		wfx_smooth(chan->wave, absolutePoint(selectionA), absolutePoint(selectionB));

		selectionA = 0;
		selectionB = 0;

		stretchToWindow();
		redraw();
		menuOpen = false;
		return;
	}
}
예제 #3
0
int gWaveform::alloc(int datasize)
{
  ratio = chan->wave->size / (float) datasize;

  if (ratio < 2)
    return 0;

  freeData();

  data.size = datasize;
  data.sup  = (int*) malloc(data.size * sizeof(int));
  data.inf  = (int*) malloc(data.size * sizeof(int));

  int offset = h() / 2;
  int zero   = y() + offset; // center, zero amplitude (-inf dB)

  /* grid frequency: store a grid point every 'gridFreq' pixel. Must be
   * even, as always */

  int gridFreq = 0;
  if (grid.level != 0) {
    gridFreq = chan->wave->size / grid.level; 
    if (gridFreq % 2 != 0)
      gridFreq--;
  }

  for (int i=0; i<data.size; i++) {

    int pp;  // point prev
    int pn;  // point next

    /* resampling the waveform, hardcore way. Many thanks to
     * http://fourier.eng.hmc.edu/e161/lectures/resize/node3.html
     * Note: we use
     *   p = j * (m-1 / n)
     * instead of
     *   p = j * (m-1 / n-1)
     * in order to obtain 'datasize' cells to parse (and not datasize-1) */

    pp = i * ((chan->wave->size - 1) / (float) datasize);
    pn = (i+1) * ((chan->wave->size - 1) / (float) datasize);

    if (pp % 2 != 0) pp -= 1;
    if (pn % 2 != 0) pn -= 1;

    float peaksup = 0.0f;
    float peakinf = 0.0f;

    /* scan the original data in chunks */

    int k = pp;
    while (k < pn) {

      if (chan->wave->data[k] > peaksup)
        peaksup = chan->wave->data[k];    // FIXME - Left data only
      else
      if (chan->wave->data[k] <= peakinf)
        peakinf = chan->wave->data[k];    // FIXME - Left data only

      /* print grid */

      if (gridFreq != 0)
        if (k % gridFreq == 0 && k != 0)
          grid.points.add(i);
      
      k += 2;
    }

    data.sup[i] = zero - (peaksup * chan->boost * offset);
    data.inf[i] = zero - (peakinf * chan->boost * offset);

    // avoid window overflow

    if (data.sup[i] < y())       data.sup[i] = y();
    if (data.inf[i] > y()+h()-1) data.inf[i] = y()+h()-1;
  }

  recalcPoints();
  return 1;
}