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

📄 sine.c

📁 Reference Implementation of G.711 standard and other voice codecs
💻 C
字号:
/*                                                         21.Mar.2000 v1.2  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  SINE.C  Description:  ~~~~~~~~~~~~  Program for generating a file with a tone, given the amplitude, the  frequency, the sampling rate, the DC level and the phase.  In this  implementation, a 16 bit resolution A/D,D/A system is the default  (changeable by the optional parameter #9)  Usage:  ~~~~~~  $ sine [-options] file         [BlockSize [NoOfBlocks [ACampl [f [fs [DCampl [phase [res]]]]]]]]  where:  file ........ is the file name;  BlockSize ... is the Block size, in samples;  NoOfBlocks .. the number of blocks to be displayed;  ACampl ...... AC amplitude of the tone; if positive, it is understood                as the PCM value; if negative, it considers the value                given as a dB value. So, if it is -20, the program                will generate a tone with AC amplitude equal to -20                dB, ie, 1638 in PCM;  f ........... tone frequency, in Hz;  fs .......... sampling frequency, in Hz;  DCampl ...... DC level of the tone, in PCM;  phase	....... the desired phase for the tone, in degrees;  res ......... digital system resolution; if not specified, the program                assumes 16 bits;  Options:  ~~~~~~~~  -dB ........... AC level is given in dB [default: linear PCM]  -ac ........... define AC tone level, in dB or PCM  -f ............ define tone frequency in Hertz   -dc ........... define DC level for tone, as a linear PCM value [default: 0]  -sf ........... define sampling frequency in Hertz [default: 8000 Hz]  -phase ........ set phase in degrees for tone [default: 0 degrees]  -blk .......... define file block size [default: 256]  -n ............ define no.of blocks to generate  -res .......... define no.of bits per sample [default: 16]  -q ............ quiet operation  -? or -help ... display on-line help message  Author:  ~~~~~~~  Simao Ferraz de Campos Neto -- CPqD/Telebras  History:  ~~~~~~~~  08.Mar.1990 v1.0 created  07.Nov.1997 v1.1 command-line options added; PCM<->dB conversions                    corrected, in particular for tones (sqrt(2) factor		   between level & peak). <simao>  21.Mar.2000 v1.2 changed memory allocation of short buffer                   data[] from static to dynamic, to prevent		   memory invasion when block sizes larger than		   256 are specified. <simao.campos@labs.comsat.com>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*//* OS definition */#ifndef MSDOS#if defined(__MSDOS__) || defined (__CYGWIN__) || defined (_MSC_VER)# define MSDOS#endif#endif/* includes in general */#include "ugstdemo.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>/* includes for OS specific directives */#if defined(MSDOS)         /* ... DOS ... */#include <fcntl.h>#include <io.h>#elif defined(VMS)         /* ... VMS ... */#include <stdlib.h>#include <perror.h>#include <file.h>#else /* ... others ... */#include <unistd.h>#endif#ifdef USE_FUNCTION#define refdB refdB_f#define v_to_dB(x) v_to_dB_f(x)double refdB_f=0;double v_to_dB_f(double x){  return (20.0*log10(x) - refdB);}#else#define v_to_dB(x) (20.0*log10(x)-refdB)#endif/* Pseudo-function definitions for the program */#define TWO_PI (8*atan(1.0))#define DEGREE_TO_RADIAN(x) (x*atan(1.0)/45.0)#define dB_to_v(x) (pow(10.0,(x+refdB)/10.0))/*  --------------------------------------------------------------------------  display_usage()  Shows program usage.  History:  ~~~~~~~~  7/Nov/1997  v1.0 Created <simao>  --------------------------------------------------------------------------*/#define P(x) printf xvoid display_usage(){  P(("Version 1.2 of 22/Mar/2000 \n\n"));   P(("  SINE.C\n"));  P(("\n"));  P(("  Program for generating a file with a tone, given the amplitude, the\n"));  P(("  frequency, the sampling rate, the DC level and the phase.  In this\n"));  P(("  implementation, a 16 bit resolution A/D,D/A system is the default\n"));  P(("  (changeable by the optional parameter #9)\n"));  P(("\n"));  P(("  Usage:\n"));  P(("  ~~~~~~\n"));  P(("  $ sine [-options] file\n"));  P(("         [BlockSize [NoOfBlocks [ACampl [f [fs [DCampl [phase [res]]]]]]]]\n"));  P(("  where:\n"));  P(("  file ........ is the file name;\n"));  P(("  BlockSize ... is the Block size, in samples;\n"));  P(("  NoOfBlocks .. the number of blocks to be displayed;\n"));  P(("  ACampl ...... AC amplitude of the tone; if positive, it is understood\n"));  P(("                as the PCM value; if negative, it considers the value\n"));  P(("                given as a dB value. So, if it is -20, the program\n"));  P(("                will generate a tone with AC amplitude equal to -20\n"));  P(("                dB, ie, 1638 in PCM;\n"));  P(("  f ........... tone frequency, in Hz;\n"));  P(("  fs .......... sampling frequency, in Hz;\n"));  P(("  DCampl ...... DC level of the tone, in PCM;\n"));  P(("  phase	....... the desired phase for the tone, in degrees;\n"));  P(("  res ......... digital system resolution; if not specified, the program\n"));  P(("                assumes 16 bits;\n"));  P(("\n"));  P(("  Options:\n"));  P(("  ~~~~~~~~\n"));  P(("  -dB ........... AC level is given in dB [default: linear PCM]\n"));  P(("  -ac ........... define AC tone level, in dB or PCM\n"));  P(("  -f ............ define tone frequency in Hertz \n"));  P(("  -dc ........... define DC level for tone, as a linear PCM value [default: 0]\n"));  P(("  -sf ........... define sampling frequency in Hertz [default: 8000 Hz]\n"));  P(("  -phase ........ set phase in degrees for tone [default: 0 degrees]\n"));  P(("  -blk .......... define file block size [default: 256]\n"));  P(("  -n ............ define no.of blocks to generate\n"));  P(("  -res .......... define no.of bits per sample [default: 16]\n"));  P(("  -q ............ quiet operation\n"));  P(("  -? or -help ... display on-line help message\n"));  /* Quit program */  exit(-128);}#undef P/* ..................... End of display_usage() ......................... *//* ********************************************************************** *//* ********************************************************************** *//* ************************* MAIN PROGRAM ******************************* *//* ********************************************************************** *//* ********************************************************************** */int main(argc,argv)int argc;char *argv[];{  int 	i,j,n;  double t;#ifndef USE_FUNCTION  double refdB=0;#endif  FILE *Fo;  static char	FileOut[150];  int	N=256, blk_no=0, DClevel=0, AD_resolution=16;#ifdef STATIC_ALLOCATION  short data[512];#else  short *data;#endif  double f=-1000, fs=8000,AClevel=-100000,phi=0,step,OverFlow;  char quiet=0, use_dB = 0;#ifdef VMS  char 		mrs[15]="mrs=";#endif  /* Check options */  if (argc < 2)    display_usage ();  else  {    while (argc > 1 && argv[1][0] == '-')      if (strcmp (argv[1], "-n") == 0)      {	/* Define no. of blocks to generate */	blk_no = atol (argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-blk") == 0)      {	/* Define input & output encoded speech bitstream format */	N = atoi(argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-dB") == 0 ||	       strcmp (argv[1], "-db") == 0 ||	       strcmp (argv[1], "-DB") == 0)      {	/* AC level is in dB */	use_dB = 1;	/* Move arg{c,v} over the option to the next argument */	argc--;	argv++;      }      else if (strcmp (argv[1], "-ac") == 0)      {	/* Define AC level */	AClevel = atof (argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-dc") == 0)      {	/* Define DC level */	DClevel = atof (argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-f") == 0)      {	/* Define tone frequency */	f = atof (argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-sf") == 0)      {	/* Define sampling frequency */	fs = atof (argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-phase") == 0)      {	/* Define phase offset, in degrees */	phi = atof (argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-res") == 0)      {	/* Define phase offset, in degrees */	AD_resolution = atoi (argv[2]);	/* Move arg{c,v} over the option to the next argument */	argc -= 2;	argv += 2;      }      else if (strcmp (argv[1], "-q") == 0)      {	/* Quiet more */	quiet = 1;	/* Move arg{c,v} over the option to the next argument */	argc--;	argv++;      }      else if (strcmp (argv[1], "-?") == 0 || strstr(argv[1], "-help"))      {	display_usage();      }      else      {	fprintf (stderr, "ERROR! Invalid option \"%s\" in command line\n\n",		 argv[1]);	display_usage ();      }  }  /* Get parameters */  GET_PAR_S(1,  "_Output file? ......................... ", FileOut);  if (AClevel==-100000)  {    if(use_dB)    {      GET_PAR_D(2, "_AC level? [dBov] ..................... ", AClevel);    }    else    {      GET_PAR_D(2, "_Tone peak value? [PCM] ............... ", AClevel);    }  }  else  {    argc++;argv++;    fprintf(stderr, "%s%-8.2f\n", use_dB?	    "_AC level? [dBov] ..................... " :	    "_Tone peak value? [PCM] ............... ", AClevel);  }  if (f<0)  {    GET_PAR_D(3, "_Desired tone frequency? [Hz] ......... ", f);  }  else  {    argc++;argv++;    fprintf(stderr, "_Desired tone frequency? [Hz] ......... %-8.2f\n", f);  }  if (blk_no==0)  {    GET_PAR_I(4, "_Number of blocks? [].................. ", blk_no);  }  else  {    argc++;argv++;  }  FIND_PAR_F(5, "_Sampling frequency? [Hz] ............. ", fs, fs);  FIND_PAR_I(6, "_DC level? [PCM] ...................... ", DClevel, DClevel);  FIND_PAR_F(7, "_Tone phase? [-90..90 degrees] ........ ", phi, phi);  FIND_PAR_I(8, "_Block length? [samples] .............. ", N, N);  FIND_PAR_I(9, "_A/D resolution [bits] ................ ",	        AD_resolution, AD_resolution);  /* Initializations */  OverFlow=pow((double)2.0, (double)(AD_resolution-1))-1.0;  refdB= v_to_dB(pow(2,AD_resolution-1));#ifdef DEBUG  printf("Ovf=%f\n",OverFlow);  printf("RefdB=%f\n",refdB);  printf("ACL=%f\n",AClevel);#endif  if (use_dB)  {    AClevel = OverFlow  * sqrt(2.0) *       pow((double)10.0, (double)(AClevel)/(double)20.0);   }#ifdef DEBUG  printf("ACL=%f\n",AClevel);#endif  /* Allocates memory */#ifndef STATIC_ALLOCATION  if ((data = (short *) calloc(N, sizeof(short))) == NULL)     HARAKIRI("Error in memory allocation!\n",10);#endif  /* Creates output file */#ifdef VMS  sprintf(&mrs[4], "%d", 2 * N);#endif  if ((Fo = fopen(FileOut, WB)) == NULL)    KILL(FileOut, 1);  /* Report of what is happening ... */  if (!quiet)  {    printf("\n ----------------------------------------------------");    printf("\n  ---> TONE FILE GENERATION REPORT");    printf("\n ----------------------------------------------------");    printf("\n Input file: ................ %8s",FileOut);    printf("\n Block Length: .............. %8d []",N);    printf("\n Number of blocks: .......... %8d []",blk_no);    printf("\n ----------------------------------------------------");    printf("\n Tone peak (before clipping): %8.0f [PCM]",AClevel);    printf("\n Tone level (AC): ........... %8.2f [dBov]",	   v_to_dB(AClevel/sqrt(2.0)));    printf("\n DC level: .................. %8d [PCM]",DClevel);    printf("\n Tone frequency: ............ %8.2f [Hz]",f);    printf("\n Sampling frequency: ........ %8.2f [Hz]",fs);    printf("\n Tone phase: ................ %8.0f [degrees]",phi);    printf("\n         or: ................ %8.5f [radians]",	   (phi=DEGREE_TO_RADIAN(phi)));    printf("\n ----------------------------------------------------\n");  }  /* Checks for overflow and aliasing; info only, no action taken */  if(floor(AClevel+DClevel) >  OverFlow ||      ceil(DClevel-AClevel)  < -OverFlow-1)  {     printf("%%SNF-W-OVERFLOW, value for the tone amplitude plus the ");    printf("DC level exceeds \n  the maximum value for your digital ");    printf("system: clipping will occur.\n");  }  if(f>fs/2)  {    printf("%%SNF-W-ALIASING, sampling frequency less than twice the ");    printf("tone frequency: aliasing\t  will occur.\n");  }  /* Generation of a sine wave */  step= TWO_PI*f/fs;  for (i=0;i<blk_no;i++)  {    n=i*N;    for(j=0;j<N;j++)    {      /* Get the frequency argument */      t=(step*(j+n)+phi);      /* Get the tone amplitude, as a float */      t=AClevel*sin(t)+DClevel;      /* Round and saturate at the overflow point, if necessary */      t+=0.5*((t>0)?1.0:((t==0)?0.0:-1.0));      data[j]=(t>OverFlow)?OverFlow:(t<-OverFlow-1)?-OverFlow-1:t;    }    /* Saving the sine; aborts program on failure */    if (fwrite(data,sizeof(short), N, Fo) != N)      KILL(FileOut, 2);  }  /* Finalizations */  fclose(Fo);#ifndef VMS  return(0);#endif}

⌨️ 快捷键说明

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