diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xaim/synthdramp.c	Fri May 20 15:19:45 2011 +0100
@@ -0,0 +1,288 @@
+/*  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 */
+
+
+
+