tomwalters@0: /* synthdramp tomwalters@0: * ------------ tomwalters@0: * tomwalters@0: * (A tidied-up version of makeping) tomwalters@0: * tomwalters@0: * original: M. Akeroyd. Autumn 1992. tomwalters@0: * tomwalters@0: * revisions: roy: 3dec92: decay parameter is now half-life. tomwalters@0: * MAA: sep93: tidied up the code, got rid of the .h file tomwalters@0: * tomwalters@0: * MAA: February 1994: added floor values. tomwalters@0: * MAA: March 1994: Added initial offsets, and 'steps' tomwalters@0: */ tomwalters@0: tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include tomwalters@0: tomwalters@0: /* the following used to be in "makeping.h" */ tomwalters@0: tomwalters@0: #define PulseFreqDef 40 /* Hz */ tomwalters@0: #define SinFreqDef 800 /* carrier freq: Hz */ tomwalters@0: #define SampRateDef 20000 /* sampling rate: samples per sec */ tomwalters@0: #define SinPhaseDef 0.0 /* of carrier wrt to pulse: degrees */ tomwalters@0: #define AmpMaxDef 10000 /* max amplitude */ tomwalters@0: #define NoOfPulsesDef 20 /* how many to make */ tomwalters@0: #define MaxNoSamplesPerWave 882000 /* limit on array size */ tomwalters@0: #define DampCoefDef 5.0 /* half-life; msecs */ tomwalters@0: #define FileNameDef "nofilespecified" tomwalters@0: #define FORWARD 2 /* "forward" == damp, */ tomwalters@0: #define BACKWARD 3 /* "backward" == ramp. tomwalters@0: * (for historical reasons). tomwalters@0: */ tomwalters@0: #define ON 1 tomwalters@0: #define OFF 0 tomwalters@0: #define PI 3.141592654 tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /*---------------------------------------------------------------------------*/ tomwalters@0: /*---------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: tomwalters@0: main(int argc, char *argv[]) tomwalters@0: { tomwalters@0: int x = 1; tomwalters@0: int helpflag = OFF; tomwalters@0: int gateoption = OFF; tomwalters@0: int toneflag = OFF; tomwalters@0: int floorflag = OFF; tomwalters@0: long pulsefreq = PulseFreqDef; tomwalters@0: long sinfreq = SinFreqDef; tomwalters@0: long samprate = SampRateDef; tomwalters@0: long ampmax = AmpMaxDef; tomwalters@0: double sinphase = SinPhaseDef; tomwalters@0: long noofpulses = NoOfPulsesDef; tomwalters@0: double dampcoef = (double) DampCoefDef; tomwalters@0: int directionflag = FORWARD; tomwalters@0: short sample_short[MaxNoSamplesPerWave]; /* the array of data ... */ tomwalters@0: tomwalters@0: char *filename = FileNameDef; tomwalters@0: FILE *filepointer; tomwalters@0: tomwalters@0: long sampleno, localsampleno, lengthwave_samples; tomwalters@0: double lengthpulse_samples; tomwalters@0: double phaserad; tomwalters@0: double expfactor; tomwalters@0: double temp; tomwalters@0: double lengthwave; tomwalters@0: double sinfreqrad; tomwalters@0: tomwalters@0: int floor = 0; tomwalters@0: int offset_ms = 0; tomwalters@0: int phase_deg = 0; tomwalters@0: long offset_samples = 0; tomwalters@0: double fraction = 0.0; tomwalters@0: long temp_samples = 0; tomwalters@0: int delay_ms = 0; tomwalters@0: long delay_samples = 0; tomwalters@0: tomwalters@0: /*---------------------------------------------------------*/ tomwalters@0: tomwalters@0: /* Options handler. Hack but it works. tomwalters@0: * .................................... tomwalters@0: */ tomwalters@0: tomwalters@0: /* special hack for '-h' */ tomwalters@0: if ((argc ==2) && (!strcmp(argv[1], "-h"))) { tomwalters@0: argc=1; /* to bypass the upcoming 'while' */ tomwalters@0: helpflag=ON;} tomwalters@0: tomwalters@0: while (x < argc ) tomwalters@0: { tomwalters@0: if (!strcmp(argv[x], "-p")) { pulsefreq=atol(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-f")) { sinfreq=atol(argv[x+1]); x += 2; } tomwalters@0: else if (!strcmp(argv[x], "-s")) { samprate=atol(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-w")) { sinphase=atof(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-m")) { ampmax=atol(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-n")) { noofpulses=atof(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-h")) { dampcoef=atof(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-floor")) { floorflag=ON; floor=atoi(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-offset")) { offset_ms=atoi(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-delay")) { delay_ms=atoi(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-phase")) { phase_deg=atoi(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-frac")) { fraction=atof(argv[x+1]); x += 2;} tomwalters@0: else if (!strcmp(argv[x], "-t")) { toneflag=ON; x += 1;} tomwalters@0: else if (!strcmp(argv[x], "-o")) { filename=argv[x+1]; x+=2;} tomwalters@0: else if (!strcmp(argv[x], "-d")) { directionflag=FORWARD; x+=1;} tomwalters@0: else if (!strcmp(argv[x], "-r")) { directionflag=BACKWARD; x+=1;} tomwalters@0: else if (!strcmp(argv[x], "-help")) { helpflag=ON; x+=1;} tomwalters@0: else if (!strcmp(argv[x], "-g")) { gateoption=ON; x+=1;} tomwalters@0: else { printf("\nUnknown Option : %s \n", argv[x]); tomwalters@0: return 1;} tomwalters@0: } tomwalters@0: tomwalters@0: if ((helpflag == ON) || (argc == 1)) tomwalters@0: {printf("\n ---------- synthdramp (Winter 1994) --------------\n"); tomwalters@0: printf("\n"); tomwalters@0: printf("Tone options : \n"); tomwalters@0: printf(" -w phase of sin wave, wrt begining of pulse default: %3.3f degs\n", SinPhaseDef); tomwalters@0: printf(" -f carrier frequency default: %d Hz\n", SinFreqDef); tomwalters@0: printf("\n"); tomwalters@0: printf("Gate options : \n"); tomwalters@0: printf(" -d damped sinusoid (default)\n"); tomwalters@0: printf(" -r ramped sinusoid \n"); tomwalters@0: printf(" -s sampling rate default: %d samp/sec\n", SampRateDef); tomwalters@0: printf(" -m max amplitude default: %d \n", AmpMaxDef); tomwalters@0: printf(" -n number of cycles in train default: %d \n", NoOfPulsesDef); tomwalters@0: printf(" -h half-life default: %3.3f \n", DampCoefDef); tomwalters@0: printf(" -p repitition rate default: %d Hz\n", PulseFreqDef); tomwalters@0: printf(" -floor floor value default: %d \n", floor); tomwalters@0: printf(" -delay delay at begining (ms) default: %d \n", delay_ms); tomwalters@0: printf("\n"); tomwalters@0: printf("'Step' options (only work if just gate is created): \n"); tomwalters@0: printf(" -offset offset time to step (ms) default: %d \n", offset_ms); tomwalters@0: printf(" -phase offset, measured as phase delay default: %d degrees\n", phase_deg); tomwalters@0: printf(" -frac fractional height of step default: 3.3f \n", fraction); tomwalters@0: printf("\n"); tomwalters@0: printf("Output options : \n"); tomwalters@0: printf(" -g gate only : no tone\n"); tomwalters@0: printf(" -t tone only : no gate\n"); tomwalters@0: printf(" -o '' output filename \n"); tomwalters@0: printf("\n"); tomwalters@0: exit(-1); tomwalters@0: } tomwalters@0: tomwalters@0: if (!strcmp(FileNameDef, filename)) tomwalters@0: { tomwalters@0: fprintf(stderr, "\n No file has been specified. Stopping. \n\n"); tomwalters@0: exit(-1); tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /*---------------------------------------------------------*/ tomwalters@0: tomwalters@0: /* convert the damping coeeficent from a half-life to whatever the internal tomwalters@0: * value is. tomwalters@0: * roy 23-11-92 thru 3-12-92) */ tomwalters@0: dampcoef = 0.693147/(dampcoef/1000) ; tomwalters@0: tomwalters@0: /* define useful things: tomwalters@0: * lengthwave: overall length of wave, in seconds. tomwalters@0: * lengthwave_samples: overlall length of wave, in samples. tomwalters@0: * lengthpulse_samples: length of each pulse, in samples. tomwalters@0: * phaserad: the phase angle, in radians as against degrees. tomwalters@0: * sinfreqrad: constant to speed the code up. tomwalters@0: */ tomwalters@0: lengthwave = (double) noofpulses / pulsefreq; tomwalters@0: lengthwave_samples = (long) samprate * noofpulses / pulsefreq; tomwalters@0: lengthpulse_samples = (double) samprate / pulsefreq; tomwalters@0: tomwalters@0: phaserad = sinphase * PI / 180; tomwalters@0: sinfreqrad = (double) 2 * PI * sinfreq; tomwalters@0: tomwalters@0: /* error-check */ tomwalters@0: if (lengthwave_samples >= MaxNoSamplesPerWave) { tomwalters@0: fprintf(stderr, "Wave too long for internal arrays. \n"); tomwalters@0: exit(-1);} tomwalters@0: tomwalters@0: /*---------------------------------------------------------*/ tomwalters@0: tomwalters@0: tomwalters@0: /* delay */ tomwalters@0: tomwalters@0: for (sampleno=0; sampleno < lengthwave_samples; sampleno++) tomwalters@0: sample_short[sampleno] = (short) 0; tomwalters@0: tomwalters@0: filepointer = fopen(filename, "w"); tomwalters@0: tomwalters@0: if (delay_ms != 0) { tomwalters@0: delay_samples = (long) samprate * delay_ms / 1000; tomwalters@0: fwrite(sample_short, 2, delay_samples, filepointer);} tomwalters@0: tomwalters@0: for (sampleno=0; sampleno < lengthwave_samples; sampleno++) tomwalters@0: sample_short[sampleno] = (short) 0; tomwalters@0: tomwalters@0: tomwalters@0: /*---------------------------------------------------------*/ tomwalters@0: tomwalters@0: /* for each sample, from 0 to the end, work out its value by (1) taking the tomwalters@0: * value of the carrier, and (2) multiplying it by the exp factor. tomwalters@0: * if the "-g" option has been called, then in effect make the exp "gate" tomwalters@0: * only ... tomwalters@0: * The results go into sample_short[]. tomwalters@0: */ tomwalters@0: tomwalters@0: /*---------------------------*/ tomwalters@0: for (sampleno=0; sampleno < lengthwave_samples; sampleno++) { tomwalters@0: tomwalters@0: temp = (double) (fmod(sampleno, lengthpulse_samples)) / samprate; tomwalters@0: expfactor = exp( -1 * dampcoef * temp ) ; /* * samprate roy */ tomwalters@0: tomwalters@0: if (directionflag == FORWARD) tomwalters@0: localsampleno = sampleno; tomwalters@0: else tomwalters@0: localsampleno = lengthwave_samples -2 - sampleno; tomwalters@0: /* -2 seems to work */ tomwalters@0: tomwalters@0: sample_short[localsampleno]= ampmax * sin(sinfreqrad * temp + phaserad) * expfactor; tomwalters@0: if (gateoption == ON) tomwalters@0: sample_short[localsampleno] = ampmax * expfactor; tomwalters@0: if (floorflag == ON) tomwalters@0: if (sample_short[localsampleno] <= floor ) tomwalters@0: sample_short[localsampleno] = (short) floor; tomwalters@0: } tomwalters@0: tomwalters@0: if (toneflag == ON) { tomwalters@0: for (sampleno=0; sampleno < lengthwave_samples; sampleno++) { tomwalters@0: temp = (double) (sampleno) / samprate; tomwalters@0: expfactor=1; tomwalters@0: sample_short[sampleno]= ampmax * sin(sinfreqrad * temp + phaserad) * expfactor;}} tomwalters@0: tomwalters@0: tomwalters@0: /*---------------------------*/ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* Only do this is step specified: ie, offset or phase ! = 0 */ tomwalters@0: tomwalters@0: offset_samples = (long) 0; tomwalters@0: tomwalters@0: if (offset_ms != 0) tomwalters@0: offset_samples = (long) samprate * offset_ms / 1000; tomwalters@0: if (phase_deg != 0) tomwalters@0: offset_samples = (long) lengthpulse_samples * phase_deg / 360; tomwalters@0: tomwalters@0: if (offset_samples != 0) { tomwalters@0: for (sampleno=0; sampleno < lengthwave_samples; sampleno++) { tomwalters@0: tomwalters@0: temp = (double) (fmod(sampleno, lengthpulse_samples)) / samprate; tomwalters@0: expfactor = exp( -1 * dampcoef * temp ) ; /* * samprate roy */ tomwalters@0: tomwalters@0: if (directionflag == FORWARD) tomwalters@0: localsampleno = sampleno; tomwalters@0: else tomwalters@0: localsampleno = lengthwave_samples -2 - sampleno; tomwalters@0: /* -2 seems to work */ tomwalters@0: tomwalters@0: temp_samples = (long) fmod(sampleno, lengthpulse_samples); tomwalters@0: if (temp_samples <= offset_samples) tomwalters@0: sample_short[localsampleno] = sample_short[localsampleno]; tomwalters@0: else tomwalters@0: /* sample_short[localsampleno]= fraction * ampmax * sin(sinfreqrad * temp + phaserad) * expfactor + sample_short[localsampleno]; tomwalters@0: * tomwalters@0: * if (gateoption == ON)*/ tomwalters@0: sample_short[localsampleno] = fraction * ampmax * expfactor + sample_short[localsampleno]; tomwalters@0: tomwalters@0: tomwalters@0: }} tomwalters@0: tomwalters@0: /*---------------------------------------------------------*/ tomwalters@0: tomwalters@0: fwrite(sample_short, 2, lengthwave_samples, filepointer); tomwalters@0: fclose(filepointer); tomwalters@0: tomwalters@0: exit(0); tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: /* the end */ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: