// ---------------------------------------------------------------- configure --
int SPECTACLE2_BASE::configure()
{
	_inbuf = new float [RTBUFSAMPS * inputChannels()];
	_input = new float [_window_len];            // interior input buffer
	_output = new float [_window_len];           // interior output buffer
	_anal_bins = new float [_fftlen + 2];        // analysis bins
	if (_inbuf == NULL || _input == NULL || _output == NULL || _anal_bins == NULL)
		return -1;
	for (int i = 0; i < _window_len; i++)
		_input[i] = _output[i] = 0.0f;

	// Delay dry output by latency to sync with wet sig.
	_dry_delay = new Odelay(_window_len);
   _dry_delay->setdelay(_latency);

	// Read index chases write index by _decimation; add 2 extra locations to
	// keep read point from stepping on write point.  Verify with asserts in
	// increment_out_*_index().
	_outframes = _decimation + 2;
	_out_read_index = _outframes - _decimation;
	_out_write_index = 0;
	_outbuf = new float [_outframes];
	if (_outbuf == NULL)
		return -1;
	for (int i = 0; i < _outframes; i++)
		_outbuf[i] = 0.0f;
	DPRINT1("_outframes: %d\n", _outframes);

	_bucket = new Obucket(_decimation, process_wrapper, (void *) this);

	_fft = new Offt(_fftlen);
	_fft_buf = _fft->getbuf();

	_anal_window = new float [_window_len];
	_synth_window = new float [_window_len];
	if (_anal_window == NULL || _synth_window == NULL)
		return -1;
	int len;
	double *window = (double *) getPFieldTable(_window_pfield_index, &len);
	if (make_windows(window, len) != 0)
		return DONT_SCHEDULE;

	if (subconfigure() != 0)
		return -1;

	return 0;
}
int SPECTACLE_BASE :: init(double p[], int n_args)
{
   float outskip = p[0];
   float inskip = p[1];
   inputdur = p[2];
   amp = p[3];
   ringdur = p[4];
   fft_len = (int) p[5];
   window_len = (int) p[6];
   window_type = getWindowType(p[7]);
   float overlap = p[8];

   /* Make sure FFT length is a power of 2 <= MAXFFTLEN and <= RTBUFSAMPS. */
   bool valid = false;
   for (int x = 1; x <= MAXFFTLEN; x *= 2) {
      if (fft_len == x) {
         valid = true;
         break;
      }
   }
   if (!valid || fft_len > MAXFFTLEN)
      return die(instname(), "FFT length must be a power of two <= %d",
                                                                  MAXFFTLEN);

// FIXME: now this isn't a problem; instead, decimation can't be larger
// than RTBUFSAMPS.  But must couch errmsg in terms of overlap and fft length,
// not decimation...
#if 0
   if (fft_len > RTBUFSAMPS)
      return die(instname(),
                 "FFT length must be a power of two less than or equal\n"
                 "to the output buffer size set in rtsetparams (currently %d).",
                 RTBUFSAMPS);
#endif
   half_fft_len = fft_len / 2;
   fund_anal_freq = SR / (float) fft_len;

   /* Make sure window length is a power of 2 >= FFT length. */
   valid = false;
   for (int x = fft_len; x <= MAXWINDOWLEN; x *= 2) {
      if (window_len == x) {
         valid = true;
         break;
      }
   }
   if (!valid)
      return die(instname(),
                     "Window length must be a power of two >= FFT length\n"
                     "(currently %d) and <= %d.", fft_len, MAXWINDOWLEN);

   /* Make sure overlap is a power of 2 in our safety range. */
   valid = false;
//FIXME: need to adjust MINOVERLAP so that iterations is never 0 in run()
// This might depend upon window_len??
   for (float x = MINOVERLAP; x <= MAXOVERLAP; x *= 2.0) {
      if (overlap == x) {
         valid = true;
         break;
      }
   }
   if (!valid)
      return die(instname(),
                 "Overlap must be a power of two between %g and %g.",
                 MINOVERLAP, MAXOVERLAP);
   int_overlap = (int) overlap;

   /* derive decimation from overlap */
   decimation = (int) (fft_len / overlap);

   DPRINT2("fft_len=%d, decimation=%d\n", fft_len, decimation);

   if (pre_init(p, n_args) != 0)    /* can modify ringdur */
      return DONT_SCHEDULE;

   iamparray = floc(1);
   if (iamparray) {
      int lenamp = fsize(1);
      tableset(SR, inputdur, lenamp, iamptabs);
   }
   else
      rtcmix_advise(instname(), "Setting input amplitude curve to all 1's.");

   oamparray = floc(2);
   if (oamparray) {
      int lenamp = fsize(2);
      tableset(SR, inputdur + ringdur, lenamp, oamptabs);
   }
   else
      rtcmix_advise(instname(), "Setting output amplitude curve to all 1's.");

   if (rtsetinput(inskip, this) == -1)
      return DONT_SCHEDULE;
   if (inchan >= inputChannels())
      return die(instname(), "You asked for channel %d of a %d-channel file.",
                                                   inchan, inputChannels());

   /* <latency> is the delay before the FFT looks at actual input rather than
      zero-padding.  Need to let inst run long enough to compensate for this.
   */
   window_len_minus_decimation = window_len - decimation;
   latency = window_len + window_len_minus_decimation;
   float latency_dur = latency * (1.0 / SR);
   if (rtsetoutput(outskip, latency_dur + inputdur + ringdur, this) == -1)
      return DONT_SCHEDULE;
   total_insamps = (int)(inputdur * SR);    /* without latency_dur */
   input_end_frame = total_insamps + latency;
   DPRINT1("input_end_frame=%d\n", input_end_frame);

   input = new float [window_len];           /* input buffer */
   output = new float [window_len];          /* output buffer */
   anal_window = new float [window_len];     /* analysis window */
   synth_window = new float [window_len];    /* synthesis window */
   fft_buf = new float [fft_len];            /* FFT buffer */
   anal_chans = new float [fft_len + 2];     /* analysis channels */

   if (make_windows() != 0)
      return DONT_SCHEDULE;

   /* Delay dry output by window_len - decimation to sync with wet sig. */
   drybuf = new float [decimation];
   dry_delay = new DLineN(window_len);
   dry_delay->setDelay((float) window_len_minus_decimation);

   /* Init iamp and oamp to starting amplitudes. */
   iamp = (iamparray == NULL) ? 1.0 : iamparray[0];
   oamp = (oamparray == NULL) ? amp : oamparray[0];

   skip = (int) (SR / (float) resetval);

   if (post_init(p, n_args) != 0)
      return DONT_SCHEDULE;

   return nSamps();
}
Beispiel #3
0
/*-----------------------------------------------------------------------------------*/
PROCESS_THREAD(program_handler_process, ev, data)
{
#ifdef WITH_LOADER_ARCH
  unsigned char err;
  struct dsc *dsc;
#endif /* WITH_LOADER_ARCH */
  unsigned char i;
  struct dsc **dscp;

  PROCESS_BEGIN();
  
  /* Create the menus */
  ctk_menu_add(&contikimenu);
#if WITH_LOADER_ARCH
  runmenuitem = ctk_menuitem_add(&contikimenu, "Run program...");
  
  make_windows();
#endif /* WITH_LOADER_ARCH */
#if QUIT_MENU
  quitmenuitem = ctk_menuitem_add(&contikimenu, "Quit");
#endif /* QUIT_MENU */
  
  displayname = NULL;
  
#if CTK_CONF_SCREENSAVER
  program_handler_screensaver[0] = 0;
#endif /* CTK_CONF_SCREENSAVER */

  while(1) {
    PROCESS_WAIT_EVENT();
    if(ev == ctk_signal_button_activate) {
#ifdef WITH_LOADER_ARCH
      if(data == (process_data_t)&loadbutton) {
	ctk_window_close(&runwindow);
	program_handler_load(name, NULL);
      } else if(data == (process_data_t)&errorokbutton) {
	ctk_dialog_close();
      }
#endif /* WITH_LOADER_ARCH */
#if QUIT_MENU
      if(data == (process_data_t)&quityesbutton) {
	ctk_draw_init();
	exit(EXIT_SUCCESS);
      } else if(data == (process_data_t)&quitnobutton) {
	ctk_dialog_close();
      }
#endif /* QUIT_MENU */
      dscp = &contikidsc[0];
      for(i = 0; i < CTK_MAXMENUITEMS; ++i) {    
	if(*dscp != NULL
#if CTK_CONF_ICONS
	  && data == (process_data_t)(*dscp)->icon
#endif /* CTK_CONF_ICONS */
	  ) {
	  RUN((*dscp)->prgname, (*dscp)->process, NULL);
	  break;
	}
	++dscp;
      }
    } else if(ev == ctk_signal_menu_activate) {
      if((struct ctk_menu *)data == &contikimenu) {
#if WITH_LOADER_ARCH
	dsc = contikidsc[contikimenu.active];
	if(dsc != NULL) {
	  RUN(dsc->prgname, dsc->process, NULL);
	} else if(contikimenu.active == runmenuitem) {
	  make_windows();
	  ctk_window_close(&runwindow);
	  ctk_window_open(&runwindow);
	  CTK_WIDGET_FOCUS(&runwindow, &nameentry);
	}
#else /* WITH_LOADER_ARCH */
	if(contikidsc[contikimenu.active] != NULL) {
	  RUN(contikidsc[contikimenu.active]->prgname,
	      contikidsc[contikimenu.active]->process,
	      NULL);
	}
#endif /* WITH_LOADER_ARCH */
#if QUIT_MENU
	if(contikimenu.active == quitmenuitem) {
	  ctk_dialog_new(&quitdialog, 24, 5);
	  CTK_WIDGET_ADD(&quitdialog, &quitdialoglabel);
	  CTK_WIDGET_ADD(&quitdialog, &quityesbutton);
	  CTK_WIDGET_ADD(&quitdialog, &quitnobutton);
	  CTK_WIDGET_FOCUS(&quitdialog, &quitnobutton);
	  ctk_dialog_open(&quitdialog);      
	}
#endif /* QUIT_MENU */
      }
#if CTK_CONF_SCREENSAVER
    } else if(ev == ctk_signal_screensaver_start) {
#if WITH_LOADER_ARCH
      if(program_handler_screensaver[0] != 0) {
	program_handler_load(program_handler_screensaver, NULL);
      }
#endif /* WITH_LOADER_ARCH */
#endif /* CTK_CONF_SCREENSAVER */
    } else if(ev == LOADER_EVENT_DISPLAY_NAME) {
#if WITH_LOADER_ARCH
      if(displayname == NULL) {
	make_windows();
	
	ctk_label_set_text(&loadingname, ((struct pnarg *)data)->name);
	ctk_dialog_open(&loadingdialog);
	process_post(&program_handler_process, LOADER_EVENT_LOAD, data);
	displayname = data;
      } else {
	/* Try again. */
	process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data);
      }
#endif /* WITH_LOADER_ARCH */
    } else if(ev == LOADER_EVENT_LOAD) {
#if WITH_LOADER_ARCH
      if(displayname == data) {
	ctk_dialog_close();
	displayname = NULL;
	log_message("Loading ", ((struct pnarg *)data)->name);
	err = LOADER_LOAD(((struct pnarg *)data)->name,
			  ((struct pnarg *)data)->arg);
	if(err != LOADER_OK) {
	  make_windows();
	  errorfilename[0] = '"';
	  strncpy(errorfilename + 1, ((struct pnarg *)data)->name,
		  sizeof(errorfilename) - 2);
	  errorfilename[1 + strlen(((struct pnarg *)data)->name)] = '"';
	  ctk_label_set_text(&errortype, (char *)errormsgs[err]);
	  ctk_dialog_open(&errordialog);
	  log_message((char *)errormsgs[err], errorfilename);
	}
	pnarg_free(data);
      } else {
	/* Try again. */
	process_post(&program_handler_process, LOADER_EVENT_DISPLAY_NAME, data);
      }
#endif /* WITH_LOADEER_ARCH */
    }
  }
  PROCESS_END();
}
Beispiel #4
0
// --------------------------------------------------------------------- init --
int SpectacleBase::init(int fftlen, int windowlen, int overlap, float srate)
{
	_fftlen = fftlen;
	_window_len = windowlen;
	_overlap = overlap;

	// Make sure FFT length is a power of 2 <= kMaxFFTLen.
	bool valid = false;
	for (int x = 1; x <= kMaxFFTLen; x *= 2) {
		if (_fftlen == x) {
			valid = true;
			break;
		}
	}
	if (!valid) {
		post("%s: FFT length must be a power of two <= %d. Setting to 1024...",
			instname(), kMaxFFTLen);
		_fftlen = 1024;
	}

	_half_fftlen = _fftlen / 2;

	// Make sure window length is a power of 2 >= FFT length.
	valid = false;
	for (int x = _fftlen; x <= kMaxWindowLen; x *= 2) {
		if (_window_len == x) {
			valid = true;
			break;
		}
	}
	if (!valid) {
		post("%s: Window length must be a power of two >= FFT length (%d)\n"
		           "and <= %d. Setting to 2048...",
				instname(), _fftlen, kMaxWindowLen);
		_window_len = _fftlen * 2;
	}

	// Make sure _overlap is a power of 2 in allowed range.
	valid = false;
	for (int x = kMinOverlap; x <= kMaxOverlap; x *= 2) {
		if (_overlap == x) {
			valid = true;
			break;
		}
	}
	if (!valid) {
		post("%s: Overlap must be a power of two between %d and %d. "
				"Setting to 2...",
		      instname(), kMinOverlap, kMaxOverlap);
		_overlap = 2;
	}

	_bin_groups = new int [_half_fftlen];

	set_srate(srate);
	set_freqrange(0.0f, 0.0f);

	// derive decimation from overlap
	_decimation = int(_fftlen / _overlap);

	_window_len_minus_decimation = _window_len - _decimation;

	DPRINT2("_fftlen=%d, _decimation=%d", _fftlen, _decimation);

	_input = new float [_window_len];            // interior input buffer
	_output = new float [_window_len];           // interior output buffer
	if (_input == NULL || _output == NULL)
		return -1;
	for (int i = 0; i < _window_len; i++)
		_input[i] = _output[i] = 0.0f;

	// Read index chases write index by _decimation; add 2 extra locations to
	// keep read point from stepping on write point.  Verify with asserts in
	// increment_out_*_index().
	_outframes = _decimation + 2;
	_out_read_index = _outframes - _decimation;
	_out_write_index = 0;
	_outbuf = new float [_outframes];
	if (_outbuf == NULL)
		return -1;
	for (int i = 0; i < _outframes; i++)
		_outbuf[i] = 0.0f;
	DPRINT1("_outframes: %d", _outframes);

	_anal_window = new float [_window_len];
	_synth_window = new float [_window_len];
	if (_anal_window == NULL || _synth_window == NULL)
		return -1;
	if (make_windows() != 0)
		return -1;

	_bucket = new Obucket(_decimation, process_wrapper, (void *) this);

	_fft = new Offt(_fftlen);
	_fft_buf = _fft->getbuf();

	return 0;
}