Mercurial > hg > aim92
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:5242703e91d3 |
---|---|
1 /* synthdramp | |
2 * ------------ | |
3 * | |
4 * (A tidied-up version of makeping) | |
5 * | |
6 * original: M. Akeroyd. Autumn 1992. | |
7 * | |
8 * revisions: roy: 3dec92: decay parameter is now half-life. | |
9 * MAA: sep93: tidied up the code, got rid of the .h file | |
10 * | |
11 * MAA: February 1994: added floor values. | |
12 * MAA: March 1994: Added initial offsets, and 'steps' | |
13 */ | |
14 | |
15 | |
16 #include <stdio.h> | |
17 #include <stdlib.h> | |
18 #include <string.h> | |
19 #include <math.h> | |
20 | |
21 /* the following used to be in "makeping.h" */ | |
22 | |
23 #define PulseFreqDef 40 /* Hz */ | |
24 #define SinFreqDef 800 /* carrier freq: Hz */ | |
25 #define SampRateDef 20000 /* sampling rate: samples per sec */ | |
26 #define SinPhaseDef 0.0 /* of carrier wrt to pulse: degrees */ | |
27 #define AmpMaxDef 10000 /* max amplitude */ | |
28 #define NoOfPulsesDef 20 /* how many to make */ | |
29 #define MaxNoSamplesPerWave 882000 /* limit on array size */ | |
30 #define DampCoefDef 5.0 /* half-life; msecs */ | |
31 #define FileNameDef "nofilespecified" | |
32 #define FORWARD 2 /* "forward" == damp, */ | |
33 #define BACKWARD 3 /* "backward" == ramp. | |
34 * (for historical reasons). | |
35 */ | |
36 #define ON 1 | |
37 #define OFF 0 | |
38 #define PI 3.141592654 | |
39 | |
40 | |
41 | |
42 | |
43 /*---------------------------------------------------------------------------*/ | |
44 /*---------------------------------------------------------------------------*/ | |
45 | |
46 | |
47 main(int argc, char *argv[]) | |
48 { | |
49 int x = 1; | |
50 int helpflag = OFF; | |
51 int gateoption = OFF; | |
52 int toneflag = OFF; | |
53 int floorflag = OFF; | |
54 long pulsefreq = PulseFreqDef; | |
55 long sinfreq = SinFreqDef; | |
56 long samprate = SampRateDef; | |
57 long ampmax = AmpMaxDef; | |
58 double sinphase = SinPhaseDef; | |
59 long noofpulses = NoOfPulsesDef; | |
60 double dampcoef = (double) DampCoefDef; | |
61 int directionflag = FORWARD; | |
62 short sample_short[MaxNoSamplesPerWave]; /* the array of data ... */ | |
63 | |
64 char *filename = FileNameDef; | |
65 FILE *filepointer; | |
66 | |
67 long sampleno, localsampleno, lengthwave_samples; | |
68 double lengthpulse_samples; | |
69 double phaserad; | |
70 double expfactor; | |
71 double temp; | |
72 double lengthwave; | |
73 double sinfreqrad; | |
74 | |
75 int floor = 0; | |
76 int offset_ms = 0; | |
77 int phase_deg = 0; | |
78 long offset_samples = 0; | |
79 double fraction = 0.0; | |
80 long temp_samples = 0; | |
81 int delay_ms = 0; | |
82 long delay_samples = 0; | |
83 | |
84 /*---------------------------------------------------------*/ | |
85 | |
86 /* Options handler. Hack but it works. | |
87 * .................................... | |
88 */ | |
89 | |
90 /* special hack for '-h' */ | |
91 if ((argc ==2) && (!strcmp(argv[1], "-h"))) { | |
92 argc=1; /* to bypass the upcoming 'while' */ | |
93 helpflag=ON;} | |
94 | |
95 while (x < argc ) | |
96 { | |
97 if (!strcmp(argv[x], "-p")) { pulsefreq=atol(argv[x+1]); x += 2;} | |
98 else if (!strcmp(argv[x], "-f")) { sinfreq=atol(argv[x+1]); x += 2; } | |
99 else if (!strcmp(argv[x], "-s")) { samprate=atol(argv[x+1]); x += 2;} | |
100 else if (!strcmp(argv[x], "-w")) { sinphase=atof(argv[x+1]); x += 2;} | |
101 else if (!strcmp(argv[x], "-m")) { ampmax=atol(argv[x+1]); x += 2;} | |
102 else if (!strcmp(argv[x], "-n")) { noofpulses=atof(argv[x+1]); x += 2;} | |
103 else if (!strcmp(argv[x], "-h")) { dampcoef=atof(argv[x+1]); x += 2;} | |
104 else if (!strcmp(argv[x], "-floor")) { floorflag=ON; floor=atoi(argv[x+1]); x += 2;} | |
105 else if (!strcmp(argv[x], "-offset")) { offset_ms=atoi(argv[x+1]); x += 2;} | |
106 else if (!strcmp(argv[x], "-delay")) { delay_ms=atoi(argv[x+1]); x += 2;} | |
107 else if (!strcmp(argv[x], "-phase")) { phase_deg=atoi(argv[x+1]); x += 2;} | |
108 else if (!strcmp(argv[x], "-frac")) { fraction=atof(argv[x+1]); x += 2;} | |
109 else if (!strcmp(argv[x], "-t")) { toneflag=ON; x += 1;} | |
110 else if (!strcmp(argv[x], "-o")) { filename=argv[x+1]; x+=2;} | |
111 else if (!strcmp(argv[x], "-d")) { directionflag=FORWARD; x+=1;} | |
112 else if (!strcmp(argv[x], "-r")) { directionflag=BACKWARD; x+=1;} | |
113 else if (!strcmp(argv[x], "-help")) { helpflag=ON; x+=1;} | |
114 else if (!strcmp(argv[x], "-g")) { gateoption=ON; x+=1;} | |
115 else { printf("\nUnknown Option : %s \n", argv[x]); | |
116 return 1;} | |
117 } | |
118 | |
119 if ((helpflag == ON) || (argc == 1)) | |
120 {printf("\n ---------- synthdramp (Winter 1994) --------------\n"); | |
121 printf("\n"); | |
122 printf("Tone options : \n"); | |
123 printf(" -w <flt> phase of sin wave, wrt begining of pulse default: %3.3f degs\n", SinPhaseDef); | |
124 printf(" -f <int> carrier frequency default: %d Hz\n", SinFreqDef); | |
125 printf("\n"); | |
126 printf("Gate options : \n"); | |
127 printf(" -d damped sinusoid (default)\n"); | |
128 printf(" -r ramped sinusoid \n"); | |
129 printf(" -s <int> sampling rate default: %d samp/sec\n", SampRateDef); | |
130 printf(" -m <int> max amplitude default: %d \n", AmpMaxDef); | |
131 printf(" -n <int> number of cycles in train default: %d \n", NoOfPulsesDef); | |
132 printf(" -h <flt> half-life default: %3.3f \n", DampCoefDef); | |
133 printf(" -p <int> repitition rate default: %d Hz\n", PulseFreqDef); | |
134 printf(" -floor <int> floor value default: %d \n", floor); | |
135 printf(" -delay <int> delay at begining (ms) default: %d \n", delay_ms); | |
136 printf("\n"); | |
137 printf("'Step' options (only work if just gate is created): \n"); | |
138 printf(" -offset <int> offset time to step (ms) default: %d \n", offset_ms); | |
139 printf(" -phase <int> offset, measured as phase delay default: %d degrees\n", phase_deg); | |
140 printf(" -frac <flt> fractional height of step default: 3.3f \n", fraction); | |
141 printf("\n"); | |
142 printf("Output options : \n"); | |
143 printf(" -g gate only : no tone\n"); | |
144 printf(" -t tone only : no gate\n"); | |
145 printf(" -o '' output filename \n"); | |
146 printf("\n"); | |
147 exit(-1); | |
148 } | |
149 | |
150 if (!strcmp(FileNameDef, filename)) | |
151 { | |
152 fprintf(stderr, "\n No file has been specified. Stopping. \n\n"); | |
153 exit(-1); | |
154 } | |
155 | |
156 | |
157 /*---------------------------------------------------------*/ | |
158 | |
159 /* convert the damping coeeficent from a half-life to whatever the internal | |
160 * value is. | |
161 * roy 23-11-92 thru 3-12-92) */ | |
162 dampcoef = 0.693147/(dampcoef/1000) ; | |
163 | |
164 /* define useful things: | |
165 * lengthwave: overall length of wave, in seconds. | |
166 * lengthwave_samples: overlall length of wave, in samples. | |
167 * lengthpulse_samples: length of each pulse, in samples. | |
168 * phaserad: the phase angle, in radians as against degrees. | |
169 * sinfreqrad: constant to speed the code up. | |
170 */ | |
171 lengthwave = (double) noofpulses / pulsefreq; | |
172 lengthwave_samples = (long) samprate * noofpulses / pulsefreq; | |
173 lengthpulse_samples = (double) samprate / pulsefreq; | |
174 | |
175 phaserad = sinphase * PI / 180; | |
176 sinfreqrad = (double) 2 * PI * sinfreq; | |
177 | |
178 /* error-check */ | |
179 if (lengthwave_samples >= MaxNoSamplesPerWave) { | |
180 fprintf(stderr, "Wave too long for internal arrays. \n"); | |
181 exit(-1);} | |
182 | |
183 /*---------------------------------------------------------*/ | |
184 | |
185 | |
186 /* delay */ | |
187 | |
188 for (sampleno=0; sampleno < lengthwave_samples; sampleno++) | |
189 sample_short[sampleno] = (short) 0; | |
190 | |
191 filepointer = fopen(filename, "w"); | |
192 | |
193 if (delay_ms != 0) { | |
194 delay_samples = (long) samprate * delay_ms / 1000; | |
195 fwrite(sample_short, 2, delay_samples, filepointer);} | |
196 | |
197 for (sampleno=0; sampleno < lengthwave_samples; sampleno++) | |
198 sample_short[sampleno] = (short) 0; | |
199 | |
200 | |
201 /*---------------------------------------------------------*/ | |
202 | |
203 /* for each sample, from 0 to the end, work out its value by (1) taking the | |
204 * value of the carrier, and (2) multiplying it by the exp factor. | |
205 * if the "-g" option has been called, then in effect make the exp "gate" | |
206 * only ... | |
207 * The results go into sample_short[]. | |
208 */ | |
209 | |
210 /*---------------------------*/ | |
211 for (sampleno=0; sampleno < lengthwave_samples; sampleno++) { | |
212 | |
213 temp = (double) (fmod(sampleno, lengthpulse_samples)) / samprate; | |
214 expfactor = exp( -1 * dampcoef * temp ) ; /* * samprate roy */ | |
215 | |
216 if (directionflag == FORWARD) | |
217 localsampleno = sampleno; | |
218 else | |
219 localsampleno = lengthwave_samples -2 - sampleno; | |
220 /* -2 seems to work */ | |
221 | |
222 sample_short[localsampleno]= ampmax * sin(sinfreqrad * temp + phaserad) * expfactor; | |
223 if (gateoption == ON) | |
224 sample_short[localsampleno] = ampmax * expfactor; | |
225 if (floorflag == ON) | |
226 if (sample_short[localsampleno] <= floor ) | |
227 sample_short[localsampleno] = (short) floor; | |
228 } | |
229 | |
230 if (toneflag == ON) { | |
231 for (sampleno=0; sampleno < lengthwave_samples; sampleno++) { | |
232 temp = (double) (sampleno) / samprate; | |
233 expfactor=1; | |
234 sample_short[sampleno]= ampmax * sin(sinfreqrad * temp + phaserad) * expfactor;}} | |
235 | |
236 | |
237 /*---------------------------*/ | |
238 | |
239 | |
240 | |
241 /* Only do this is step specified: ie, offset or phase ! = 0 */ | |
242 | |
243 offset_samples = (long) 0; | |
244 | |
245 if (offset_ms != 0) | |
246 offset_samples = (long) samprate * offset_ms / 1000; | |
247 if (phase_deg != 0) | |
248 offset_samples = (long) lengthpulse_samples * phase_deg / 360; | |
249 | |
250 if (offset_samples != 0) { | |
251 for (sampleno=0; sampleno < lengthwave_samples; sampleno++) { | |
252 | |
253 temp = (double) (fmod(sampleno, lengthpulse_samples)) / samprate; | |
254 expfactor = exp( -1 * dampcoef * temp ) ; /* * samprate roy */ | |
255 | |
256 if (directionflag == FORWARD) | |
257 localsampleno = sampleno; | |
258 else | |
259 localsampleno = lengthwave_samples -2 - sampleno; | |
260 /* -2 seems to work */ | |
261 | |
262 temp_samples = (long) fmod(sampleno, lengthpulse_samples); | |
263 if (temp_samples <= offset_samples) | |
264 sample_short[localsampleno] = sample_short[localsampleno]; | |
265 else | |
266 /* sample_short[localsampleno]= fraction * ampmax * sin(sinfreqrad * temp + phaserad) * expfactor + sample_short[localsampleno]; | |
267 * | |
268 * if (gateoption == ON)*/ | |
269 sample_short[localsampleno] = fraction * ampmax * expfactor + sample_short[localsampleno]; | |
270 | |
271 | |
272 }} | |
273 | |
274 /*---------------------------------------------------------*/ | |
275 | |
276 fwrite(sample_short, 2, lengthwave_samples, filepointer); | |
277 fclose(filepointer); | |
278 | |
279 exit(0); | |
280 | |
281 } | |
282 | |
283 | |
284 /* the end */ | |
285 | |
286 | |
287 | |
288 |