view xaim/synthdramp.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
line wrap: on
line source
/*  synthdramp
*   ------------
*
*   (A tidied-up version of makeping)
*    
*   original:   M. Akeroyd. Autumn 1992.
*
*   revisions:  roy: 3dec92: decay parameter is now half-life.
*               MAA:  sep93: tidied up the code, got rid of the .h file
*
*               MAA: February 1994: added floor values.
*               MAA: March 1994: Added initial offsets, and 'steps'
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

/* the following used to be in "makeping.h" */

#define PulseFreqDef 40                 /* Hz */
#define SinFreqDef 800                  /* carrier freq: Hz */
#define SampRateDef 20000               /* sampling rate: samples per sec */
#define SinPhaseDef 0.0                 /* of carrier wrt to pulse: degrees */
#define AmpMaxDef 10000                 /* max amplitude */
#define NoOfPulsesDef 20                /* how many to make */
#define MaxNoSamplesPerWave 882000      /* limit on array size */
#define DampCoefDef 5.0                 /* half-life; msecs */
#define FileNameDef "nofilespecified"    
#define FORWARD 2                       /* "forward" == damp, */
#define BACKWARD 3        		/* "backward" == ramp. 
					 * (for historical reasons).
					 */
#define ON 1
#define OFF 0
#define PI 3.141592654




/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/


main(int argc, char *argv[])
{
  int x = 1;
  int helpflag = OFF;
  int gateoption = OFF;
  int toneflag = OFF;
  int floorflag = OFF;
  long pulsefreq = PulseFreqDef;   
  long sinfreq = SinFreqDef;       
  long samprate = SampRateDef;     
  long ampmax = AmpMaxDef;         
  double sinphase = SinPhaseDef;   
  long noofpulses = NoOfPulsesDef;               
  double dampcoef = (double) DampCoefDef;
  int directionflag = FORWARD;
  short sample_short[MaxNoSamplesPerWave];         /* the array of data ... */

  char *filename = FileNameDef;
  FILE *filepointer;

  long sampleno, localsampleno,  lengthwave_samples;
  double lengthpulse_samples;
  double phaserad;
  double expfactor;
  double temp;
  double lengthwave;
  double sinfreqrad;
  
  int floor = 0;
  int offset_ms = 0;
  int phase_deg = 0;
  long offset_samples = 0;
  double fraction = 0.0;
  long temp_samples = 0;
  int delay_ms = 0;
  long delay_samples = 0;

/*---------------------------------------------------------*/

/* Options handler. Hack but it works.
*  ....................................
*/

  /* special hack for '-h' */
  if ((argc ==2) && (!strcmp(argv[1], "-h"))) {
    argc=1;      /* to bypass the upcoming 'while' */
    helpflag=ON;}

  while (x < argc )
    {
      if (!strcmp(argv[x], "-p")) { pulsefreq=atol(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-f")) { sinfreq=atol(argv[x+1]); x += 2; }
      else if (!strcmp(argv[x], "-s")) { samprate=atol(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-w")) { sinphase=atof(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-m")) { ampmax=atol(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-n")) { noofpulses=atof(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-h")) { dampcoef=atof(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-floor")) { floorflag=ON; floor=atoi(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-offset")) { offset_ms=atoi(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-delay")) { delay_ms=atoi(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-phase")) { phase_deg=atoi(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-frac")) { fraction=atof(argv[x+1]); x += 2;}
      else if (!strcmp(argv[x], "-t")) { toneflag=ON; x += 1;}
      else if (!strcmp(argv[x], "-o")) { filename=argv[x+1]; x+=2;}
      else if (!strcmp(argv[x], "-d")) { directionflag=FORWARD; x+=1;}
      else if (!strcmp(argv[x], "-r")) { directionflag=BACKWARD; x+=1;}
      else if (!strcmp(argv[x], "-help")) { helpflag=ON; x+=1;}
      else if (!strcmp(argv[x], "-g")) { gateoption=ON; x+=1;}
      else { printf("\nUnknown Option : %s \n", argv[x]);
               return 1;}
    }

  if ((helpflag == ON) || (argc == 1))
    {printf("\n   ----------        synthdramp (Winter 1994)     --------------\n");
     printf("\n");
     printf("Tone options : \n");
     printf(" -w <flt>      phase of sin wave, wrt begining of pulse  default: %3.3f degs\n", SinPhaseDef);
     printf(" -f <int>      carrier frequency                         default: %d Hz\n", SinFreqDef);
     printf("\n");
     printf("Gate options : \n");
     printf(" -d            damped sinusoid (default)\n");
     printf(" -r            ramped sinusoid          \n");
     printf(" -s <int>      sampling rate                             default: %d samp/sec\n", SampRateDef);
     printf(" -m <int>      max amplitude                             default: %d \n", AmpMaxDef);
     printf(" -n <int>      number of cycles in train                 default: %d \n", NoOfPulsesDef);
     printf(" -h <flt>      half-life                                 default: %3.3f \n", DampCoefDef);
     printf(" -p <int>      repitition rate                           default: %d Hz\n", PulseFreqDef);
     printf(" -floor <int>  floor value                               default: %d \n", floor);
     printf(" -delay <int>  delay at begining (ms)                    default: %d \n", delay_ms);
     printf("\n");
     printf("'Step' options (only work if just gate is created): \n");
     printf(" -offset <int> offset time to step (ms)                  default: %d \n", offset_ms);
     printf(" -phase <int>  offset, measured as phase delay           default: %d degrees\n", phase_deg);
     printf(" -frac  <flt>  fractional height of step                 default: 3.3f \n", fraction);
     printf("\n");
     printf("Output options : \n");
     printf(" -g            gate only : no tone\n");
     printf(" -t            tone only : no gate\n");
     printf(" -o ''         output filename \n");
     printf("\n");
     exit(-1);
   }

  if (!strcmp(FileNameDef, filename))
    {
      fprintf(stderr, "\n No file has been specified. Stopping. \n\n");
      exit(-1);
    }


/*---------------------------------------------------------*/

  /* convert the damping coeeficent from a half-life to whatever the internal
   * value is.
   * roy 23-11-92 thru 3-12-92) */
  dampcoef = 0.693147/(dampcoef/1000) ;

  /* define useful things: 
   * lengthwave: overall length of wave, in seconds.
   * lengthwave_samples: overlall length of wave, in samples.
   * lengthpulse_samples: length of each pulse, in samples.
   * phaserad: the phase angle, in radians as against degrees.
   * sinfreqrad: constant to speed the code up.
   */
  lengthwave = (double) noofpulses / pulsefreq;       
  lengthwave_samples = (long) samprate * noofpulses / pulsefreq;       
  lengthpulse_samples = (double) samprate / pulsefreq;

  phaserad = sinphase * PI / 180;
  sinfreqrad = (double) 2 * PI * sinfreq;

  /* error-check */
  if (lengthwave_samples >= MaxNoSamplesPerWave) {
    fprintf(stderr, "Wave too long for internal arrays. \n");
    exit(-1);}
  
/*---------------------------------------------------------*/


/* delay */

  for (sampleno=0; sampleno < lengthwave_samples; sampleno++) 
    sample_short[sampleno] = (short) 0;

  filepointer = fopen(filename, "w"); 

  if (delay_ms != 0) {
    delay_samples = (long) samprate * delay_ms / 1000;
    fwrite(sample_short, 2, delay_samples, filepointer);}

  for (sampleno=0; sampleno < lengthwave_samples; sampleno++) 
	sample_short[sampleno] = (short) 0;


/*---------------------------------------------------------*/

  /* for each sample, from 0 to the end, work out its value by (1) taking the 
   * value of the carrier, and (2) multiplying it by the exp factor.
   * if the "-g" option has been called, then in effect make the exp "gate"
   * only ...
   * The results go into sample_short[].
   */

/*---------------------------*/
  for (sampleno=0; sampleno < lengthwave_samples; sampleno++) {

      temp = (double) (fmod(sampleno, lengthpulse_samples)) / samprate; 
      expfactor = exp( -1 * dampcoef * temp ) ; /* * samprate  roy */

      if (directionflag == FORWARD)
	localsampleno = sampleno;
      else
	localsampleno = lengthwave_samples -2  - sampleno;         
        /* -2 seems to work */
      
      sample_short[localsampleno]= ampmax * sin(sinfreqrad * temp + phaserad) * expfactor;
      if (gateoption == ON)
	sample_short[localsampleno] = ampmax * expfactor;
     if (floorflag == ON)  
      if (sample_short[localsampleno] <= floor )
	sample_short[localsampleno] = (short) floor;
    }

  if (toneflag == ON) {
    for (sampleno=0; sampleno < lengthwave_samples; sampleno++) {
      temp = (double) (sampleno) / samprate; 
      expfactor=1;
      sample_short[sampleno]= ampmax * sin(sinfreqrad * temp + phaserad) * expfactor;}}


/*---------------------------*/



/* Only do this is step specified: ie, offset or phase ! = 0 */

  offset_samples = (long) 0;

  if (offset_ms != 0) 
    offset_samples = (long) samprate * offset_ms / 1000;
  if (phase_deg != 0) 
    offset_samples = (long) lengthpulse_samples * phase_deg / 360;

  if (offset_samples != 0) {
    for (sampleno=0; sampleno < lengthwave_samples; sampleno++) {
      
      temp = (double) (fmod(sampleno, lengthpulse_samples)) / samprate; 
      expfactor = exp( -1 * dampcoef * temp ) ; /* * samprate  roy */
      
      if (directionflag == FORWARD)
	localsampleno = sampleno;
      else
	localsampleno = lengthwave_samples -2  - sampleno;         
      /* -2 seems to work */

      temp_samples = (long) fmod(sampleno, lengthpulse_samples);
      if (temp_samples <= offset_samples)
	sample_short[localsampleno] = sample_short[localsampleno];
      else
/*	sample_short[localsampleno]= fraction * ampmax * sin(sinfreqrad * temp + phaserad) * expfactor + sample_short[localsampleno];
*
*      if (gateoption == ON)*/
	sample_short[localsampleno] = fraction * ampmax * expfactor + sample_short[localsampleno];  

    
    }}

/*---------------------------------------------------------*/

  fwrite(sample_short, 2, lengthwave_samples, filepointer);        
  fclose(filepointer);
  
  exit(0);

}


/* the end */