⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xspect.c

📁 speech signal process tools
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (sp->nfft <= 512)	{	  sp->nfft *= 2;	  if (sp->yinterp >= 2)	/* Keep vertical size constant, if possible. */	    sp->yinterp /= 2;	}      else	{	  i = 1024;		/* biggest FFT available on DSP board */	  sp->yinterp = 1;	/* assumes vertical display size <= 900				 * pixels */	  sprintf (notice_msg,		   "Specified window size too big; window limited to %fms.",		   (1000.0 * i) / freq);	  show_notice (0, notice_msg);	  break;	}    }  sp->window_size = ((double) i) / freq;  return (TRUE);}/*************************************************************************/Signal *spectrogram (sig, type, start, end, output)     Signal *sig;     double start, end;     char *type, *output;{  Xv_Cursor cursor;  Canvas canvas;  Spectrogram *spect;  short *p;  int wasopen;  double dtmp;  Signal *ss, *spgm_32 (), *spgm_32C (), *e_spect (), *e_spgm ();  View *view;  int is_p_shorts, esps_ok;  if (!sig)    return (NULL);  if (!strcmp (type, "narrowband"))    spect_params = nb_spect_params;  else    spect_params = wb_spect_params;  if (!(spect = new_spectrogram (sig)))    {      show_notice (1, "xwaves couldn't create spectrogram signal.");      return (NULL);    }  if (end > (dtmp = sig->start_time + ((double) sig->file_size) / sig->freq))    end = dtmp;  if (start < sig->start_time)    start = sig->start_time;  /* don't create absurdly short (spatially speaking) spectrograms */  if ((end - start) / spect->window_step < 8.0)    goto free_bailout;  spect->start_time = start;  spect->end_time = end;  spect->outname = savestring (output);  is_p_shorts = sig->type & (VECTOR_SIGNALS | APERIODIC_SIGNALS | VAR_REC_SIGNALS);  esps_ok = sig->header    && sig->header->magic == ESPS_MAGIC    && sig->file == SIG_CLOSED;  if ((!use_dsp32 && esps_ok) || (esps_ok && !sig->header->e_scrsd))    ss = e_spect (spect);	/* No board; up-to-date ESPS file */  /*   * or any old ESPS file (including FEA_SD not read as scrsd) (might work)   */  else if (!is_p_shorts || (is_p_shorts && sig->dim != 1))    {      show_notice (1, "Data type not supported in spectrogram().");      return (NULL);    }  else if ((use_dsp32 && ((dsp_type == DSP32_FAB2) || (dsp_type == DSP32C_VME)))	   && ((start < BUF_START_TIME (sig)) || (end > BUF_END_TIME (sig))))    {      wasopen = (sig->file >= 0);      if (!sig->utils->read_data (sig, start, end - start))	{	  sprintf (notice_msg,	      "Can't read specified data segment (%f %f) in spectrogram().",		   start, end - start);	  show_notice (1, notice_msg);	  goto free_bailout;	}      if (dsp_type == DSP32_FAB2)	ss = spgm_32 (spect);      else if (dsp_type == DSP32C_VME)	ss = spgm_32C (spect);      if (sig->views)	{			/* restore displayed segment, if any */	  start = sig->views->start_time;	  end = ET (sig->views) - start;	/* i.e. not end, but duration */	  get_view_segment (sig->views, &start, &end);	}      if (!wasopen)	close_sig_file (sig);    }  else    {				/* use segment already in memory */      if (use_dsp32 && dsp_type == DSP32_FAB2)	ss = spgm_32 (spect);      else if (use_dsp32 && dsp_type == DSP32C_VME)	ss = spgm_32C (spect);      else	ss = e_spgm (spect);    }  link_new_signal ((Object *) sig->obj, ss);	/* put at head of signal list */  if (!(view = new_spect_display (ss)))    {      free_signal (ss);      goto free_bailout;    }  return (ss);free_bailout:  if (spect)    free_spectrogram (spect);  return (NULL);}/*************************************************************************/View *new_spect_display (ss)     Signal *ss;{  View *view;  if (!(view = new_spect_view (ss, FIXED_SCALE, NULL)))    return (NULL);  if (!new_spect_window (ss))    return (NULL);  update_window_titles (ss);  return (view);}#define RETURN(x) {DSP_UNLOCK; return (x);}/*************************************************************************/Signal *spgm_32 (sp)     Spectrogram *sp;{#if defined(DS3100) || defined(APOLLO_68K) || defined(STARDENT_3000) || defined(hpux) ||  defined(SONY) || defined(M5600) || defined(IBM_RS6000) || defined(SG) || defined(OS5) || defined(DEC_ALPHA) || defined(LINUX)  return;#else  int size, step, nfrm, nsamps, nx, ny, x, init = 1;  register int i, cnt;  register short *p, *q, *data;  static float fwind[1024];  struct mem_dpr    {      short nfft, win, step, ni;      float pre, qc[5], qbw[5];      short fnx, fny, fni, fnh;      float fh[100];      float window[512];    }  dp;  char **dpp;  Signal *ss;  struct header *hdr;  double sf;  char comment[300];  char name[200], *cp, *full_path ();  static short bitmap[2048];  Signal *sig;  void spblit ();  static int INBUF_CHARS = INBUF_CHARS_32;  static int INBUF_SHORTS = INBUF_SHORTS_32;  char *dsp_bin = NULL;  if (!sp || !(sig = sp->sig))    {      show_notice (1, "Bad argument to spgm_32.");      return NULL;    }  switch (DSP_LOCK (dsp32_wait))    {    case LCKFIL_OK:      break;    case LCKFIL_INUSE:      show_notice (1, "DSP board in use.");      return NULL;      break;    default:    case LCKFIL_ERR:      show_notice (1,		"Error in trying to secure exclusive access to DSP board.");      return NULL;      break;    }  if (use_spect_prog && spect_prog)    dsp_bin = FIND_FAB2_BIN (NULL, spect_prog);  if (!(use_spect_prog && setup_dsp (dsp_bin, ALWAYS_LOAD) ||	setup_dsp ((cp = FIND_FAB2_BIN (NULL, "dspgm")), ALWAYS_LOAD)))    {      sprintf (notice_msg, "Couldn't load dsp32 program %s or default %s.",	       spect_prog, cp);      show_notice (1, notice_msg);      RETURN (NULL)    }  if (dsp_bin)    free (dsp_bin);  if (cp)    free (cp);  dsprg (0, C_RUN, 0xffff001b);	/* start prog. (it will wait for param load) */  dp.nfft = sp->nfft;		/* stuff spectrogram parameters to board */  dp.win = size = (0.5 + (sig->freq * sp->window_size));  if (size > INBUF_SHORTS / 2)    {      sprintf (notice_msg, "%s (%d)\n%s (%d).",	       "Requested window size for spectrogram",	       size,	       "exceeds available buffer size",	       INBUF_SHORTS);      show_notice (1, notice_msg);      RETURN (NULL)    }  dp.step = step = (0.5 + (sig->freq * sp->window_step));  if ((size < 4) || !step)    {      sprintf (notice_msg,	       "Unreasonable step (%d) or window (%d) size in spgm_32.",	       step, size);      show_notice (1, notice_msg);      RETURN (NULL)    }  dp.ni = sp->yinterp;  dp.qc[0] = sp->q_thresh;  dp.qc[1] = sp->agc_ratio;  dp.qc[2] = sp->q_step;  dp.qc[3] = sp->var_ratio;  dp.qbw[0] = sp->q_thresh + 60;  dp.qbw[1] = sp->agc_ratio;  dp.qbw[2] = sp->q_step * 15;  dp.qbw[3] = sp->var_ratio;  dp.pre = sp->preemp;  dp.fnx = sp->xdith;  dp.fny = sp->ydith;  if (!do_color)    dp.fni = sp->yinterp;	/* Also used as a flag to skip dithering */  else    dp.fni = 0;			/* when computing color/grayscale				 * spectrograms. */  dp.fnh = sp->xdith * sp->ydith;  for (i = 0; i < dp.fnh; i++)    dp.fh[i] = sp->dimp[i];  if (!get_float_window (fwind, size, sp->window_type))    {      show_notice (1, "Can't get_float_window() in spgm_32.");      RETURN (NULL)    }  for (i = 0, cnt = (size + 1) / 2; i < cnt; i++)    dp.window[i] = fwind[i];  /*   * Now blast the structure to the dsp32 board as a short array. This is   * necessary to assure that the actual transfers are shorts, since the   * 680xx and SPARC architectures differ and the assemblers do different   * things.   */  for (i = sizeof (struct mem_dpr) / 2, p = (short *) &dp, q = (short *) sh_mem; i-- > 0;)    *q++ = *p++;  dsprg (0, C_PIR);		/* notify dsp32 that params are loaded */  /* nsamps is total number of samples to be processed */  nsamps = (0.5 + ((sp->end_time - sp->start_time) * sig->freq));  ny = (sp->yinterp * sp->nfft) / 2;	/* number of pixels per spectrum */  /* number of time-axis pixels forced to be modulo sizeof(int) */  nx = ((int) (1 + ((nsamps - size) / step)) / sizeof (int)) * sizeof (int);  if (nx <= 0)    {      show_notice (1, "Spectrogram too short to be computed in spgm_32.");      RETURN (NULL)    }  for (i = 0; i < 1000; i++)	/* wait for params acknowledge */    if (dsprg (0, C_PCR) & PCR_PIF)      break;  if (i >= 1000)    {      show_notice (1, "DSP32 board/program not responding in spgm_32.");      RETURN (NULL)		/* dead board? */    }  /*   * get input data address.  Note that this assumes all input data in   * memory!   */  if (!sig->data      || !(data = ((short **) sig->data)[0]))    {      show_notice (1, "NULL signal data in spgm_32.");      RETURN (NULL)    }  else    data += time_to_index (sig, sp->start_time);  /* nfrm will be the number of frames computed with each call to the dsp32 */  /* Need space for dithered version? (need 1 short/row for returned bitmap) */  nfrm = 2 * (INBUF_CHARS - ((do_color) ? 0 : ny)) / ny;	/* Limit by output buf								 * size */  nfrm &= ~1;			/* force an even number */  if ((step * nfrm) > (INBUF_SHORTS - size))	/* or is it limited by input						 * buf? */    nfrm = ((INBUF_SHORTS - size) / step) & ~1;		/* force even number */  if (!nfrm)    {      show_notice (1,		   "Specified spectrogram parameters exceed available dsp32 buffer space.");      RETURN (NULL)    }  if (!do_color && (nfrm > 16))    nfrm = 16;			/* output limited by shortint size */  /* Now prepare the output signal structure. */  if (sp->outname && *sp->outname)    strcpy (name, sp->outname);  else    sprintf (name, "%s.spgm", sp->signame);	/* this SHOULD be made unique */  if (!(ss = new_signal (name, SIG_NEW,			 dup_header (sig->header), NULL, nx,			 1.0 / sp->window_step, ny)))    {      show_notice (1, "Can't make new_signal() in spgm_32.");      RETURN (NULL)    }  if (ss->header && ss->header->magic == ESPS_MAGIC && ss->header->esps_hdr)    {      hdr = new_header (FT_FEA);      sf = sp->sigfreq;      init_feaspec_hd (hdr, FALSE, SPFMT_SYM_EDGE, SPTYP_DB,		       TRUE, (long) ny, SPFRM_FIXED, (float *) NULL,		       sf, (long) ROUND (sp->window_size * sf), BYTE);      set_pvd (hdr);      sprintf (comment,	       "xwaves spectrogram: start_time %g end_time %g signal %s\n",	       sp->start_time, sp->end_time, sig->name);      add_comment (hdr, comment);      ss->header->esps_hdr = hdr;    }  ss->band = sp->sigfreq / 2.0;  ss->band_low = 0.0;  ss->params = (caddr_t) sp;  if (!(dpp = (char **) malloc (sizeof (char *) * ny)))    {      show_notice (1, "Can't malloc pointer array in spgm_32.");      RETURN (NULL)    }  for (i = 0; i < ny; i++)    {      if (!(dpp[i] = malloc (nx)))	{	  show_notice (1, "Can't malloc row in spgm_32.");	}    }  ss->data = (caddr_t) dpp;	/* output signal: the spectrogram */  p = (short *) sh_mem;		/* point to shared dsp32 memory */  *p++ = cnt = size + 1;	/* one extra sample for preemphasis on board */  *p++ = 0;			/* 1st call to board just buffers data */#ifdef SPGM_CENTER_ON_START  for (i = size / 2; i--;)    *p++ = 0;			/* Center initial window on data start */  cnt -= size / 2;		/* by padding with zeros. */#endif  do    {      *p++ = *data++;    }  while (--cnt);  dsprg (0, C_PIR);		/* let dsp know that data has been sent */  if (!do_color)    {				/* create a bitmap array for dithered image */      sp->bitmap = XV_NULL;      /* ! *//* Can't handle dithered bitmaps done on the board. */      /*       * if((sp->bitmap = (Server_image) xv_create(XV_NULL, SERVER_IMAGE,       * XV_WIDTH,          nx, XV_HEIGHT,          ny, SERVER_IMAGE_DEPTH,       * 1, 0)) == XV_NULL) show_notice(1, "Can't create a server image in       * spgm_32.");       */    }  for (i = 0; i < 10000; i++)	/* Wait for dsp32 acknowledge. */    if (dsprg (0, C_PCR) & PCR_PIF)      break;/**************************************************************************/  for (x = 0; x < nx; x += nfrm)    {				/* main loop running dsp32 */      /* now give him data */      if (nx - x < nfrm)	nfrm = nx - x;		/* This MUST be even! */      p = (short *) sh_mem;      *p++ = cnt = nfrm * step;      *p++ = nfrm;      if (nsamps)	{			/* out of data? */	  if ((nsamps -= cnt) < 0)	    cnt += nsamps;	  do	    {	      *p++ = *data++;	    }	  while (--cnt);	  if (nsamps < 0)	    cnt = -nsamps;	}      if (cnt)	do	  {	    *p++ = 0;	  }	while (--cnt);      dsprg (0, C_PIR);		/* let dsp know that data has been sent */      if (sp->bitmap && x)	{			/* blit the dithered image into a server				 * image */	  spblit ((Server_image) sp->bitmap, bitmap, ny, nfrm, init);	  /* (from previous batch) */	  init = 0;	}      for (i = 0; i < 100000; i++)	/* wait for computations to finish. */	if (dsprg (0, C_PCR) & PCR_PIF)	  break;      /* upload results */      {	register short *q = (short *) sh_mem;	int nk = nfrm / sizeof (short);	for (i = 0; i < ny; i++)	  {	    p = (short *) (dpp[i] + x);	    cnt = nk;	    if (cnt > 0)	      do		{		  *p++ = *q++;		}	      while (--cnt);	  }	if (sp->bitmap)		/* copy the dithered image into a safe place */	  for (p = bitmap + ny, i = ny; i-- > 0;)	    *--p = *q++;      }    }  if (sp->bitmap)		/* blit the final dithered image into a				 * server image */    spblit ((Server_image) sp->bitmap, bitmap, ny, nfrm, -1);  ss->type = P_CHARS | SIG_SPECTROGRAM;  ss->file_size = ss->buff_size = nx;#ifdef SPGM_CENTER_ON_START  ss->start_time = sp->start_time;#else  ss->start_time = sp->start_time + (sp->window_size / 2.0);#endif  ss->freq = sig->freq / step;  ss->end_time = sp->start_time + ((double) nx) / ss->freq;  ss->version += 1;  head_printf (ss->header, "version", &(ss->version));  head_printf (ss->header, "type_code", &(ss->type));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -