Mercurial > hg > aim92
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 */ + + + +