tomwalters@0
|
1 /*
|
tomwalters@0
|
2 tone.c generate a pure tone.
|
tomwalters@0
|
3 ------
|
tomwalters@0
|
4 Generate samples of a sine wave at a given sample rate.
|
tomwalters@0
|
5 Specify wave amplitude, and frequency (in Hz or kHz), or alternatively
|
tomwalters@0
|
6 period (in s, ms, or p (sample points) ). If both period and frequency
|
tomwalters@0
|
7 are specified, then the given period takes precedence.
|
tomwalters@0
|
8 If S is the samplerate, and Ts=1/S is the sample interval,
|
tomwalters@0
|
9 then each sample of a sine wave of period T samples is given by:
|
tomwalters@0
|
10 sin(n*(Ts/T)*TWOPI) for n=0,1,2,...
|
tomwalters@0
|
11 Output samples in the given datatype for the given waveform duration.
|
tomwalters@0
|
12
|
tomwalters@0
|
13
|
tomwalters@0
|
14 Examples:
|
tomwalters@0
|
15
|
tomwalters@0
|
16 1. Sine wave with period 10ms sampled at 10kHz, (100 sample points per period)
|
tomwalters@0
|
17
|
tomwalters@0
|
18 tone period=10ms samplerate=10kHz | x11plot
|
tomwalters@0
|
19
|
tomwalters@0
|
20 2. Sine wave with frequency 100Hz sampled at 20kHz
|
tomwalters@0
|
21
|
tomwalters@0
|
22 tone frequency=100Hz | x11plot
|
tomwalters@0
|
23
|
tomwalters@0
|
24 3. Sine wave with period 100 sample points, with dc-offset set equal to
|
tomwalters@0
|
25 amplitude of 500 so that waveform is just non-negative.
|
tomwalters@0
|
26
|
tomwalters@0
|
27 tone period=100p amplitude=500 offset=500 | x11plot
|
tomwalters@0
|
28
|
tomwalters@0
|
29 4. Quarter cycle of a sine wave with 8ms period.
|
tomwalters@0
|
30
|
tomwalters@0
|
31 tone period=8ms duration=2ms | x11plot
|
tomwalters@0
|
32
|
tomwalters@0
|
33 */
|
tomwalters@0
|
34
|
tomwalters@0
|
35 #include <stdio.h>
|
tomwalters@0
|
36 #include <math.h>
|
tomwalters@0
|
37 #include "options.h"
|
tomwalters@0
|
38 #include "units.h"
|
tomwalters@0
|
39 #include "strmatch.h"
|
tomwalters@0
|
40
|
tomwalters@0
|
41 #define TWOPI 6.28318530717
|
tomwalters@0
|
42
|
tomwalters@0
|
43 char applic[] = "generate a pure tone. " ;
|
tomwalters@0
|
44 char usage[] = "tone [options]" ;
|
tomwalters@0
|
45
|
tomwalters@0
|
46 static char *helpstr, *debugstr, *sampstr, *perstr, *freqstr, *astr, *ostr, *dstr, *typestr ;
|
tomwalters@0
|
47 static char *phasestr ;
|
tomwalters@0
|
48
|
tomwalters@0
|
49 static Options option[] = {
|
tomwalters@0
|
50 { "help" , "off" , &helpstr , "help" , DEBUG },
|
tomwalters@0
|
51 { "debug" , "off" , &debugstr , "debugging switch" , DEBUG },
|
tomwalters@0
|
52 { "samplerate", "20kHz" , &sampstr , "samplerate " , VAL },
|
tomwalters@0
|
53 { "period" , "8ms" , &perstr , "period of waveform" , VAL },
|
tomwalters@0
|
54 { "frequency" , "125Hz" , &freqstr , "frequency of waveform" , VAL },
|
tomwalters@0
|
55 { "phase" , "0" , &phasestr , "phase offset" , VAL },
|
tomwalters@0
|
56 { "amplitude" , "512" , &astr , "amplitude of waveform" , VAL },
|
tomwalters@0
|
57 { "mean" , "0" , &ostr , "mean value of waveform" , VAL },
|
tomwalters@0
|
58 { "duration" , "500ms" , &dstr , "duration of waveform" , VAL },
|
tomwalters@0
|
59 { "type" , "short" , &typestr , "output datatype" , VAL },
|
tomwalters@0
|
60 ( char * ) 0 } ;
|
tomwalters@0
|
61
|
tomwalters@0
|
62
|
tomwalters@0
|
63 int samplerate ;
|
tomwalters@0
|
64 float amplitude ;
|
tomwalters@0
|
65 float offset ;
|
tomwalters@0
|
66 int type ; /* datatype index */
|
tomwalters@0
|
67
|
tomwalters@0
|
68 main(argc, argv)
|
tomwalters@0
|
69 int argc ;
|
tomwalters@0
|
70 char *argv[] ;
|
tomwalters@0
|
71 {
|
tomwalters@0
|
72 float T=0, Tr, r, y ;
|
tomwalters@0
|
73 int i, n ;
|
tomwalters@0
|
74
|
tomwalters@0
|
75 getopts( option,argc,argv ) ;
|
tomwalters@0
|
76 if ( !isoff( helpstr ) )
|
tomwalters@0
|
77 helpopts3( helpstr, argv[0], applic, usage, option ) ;
|
tomwalters@0
|
78
|
tomwalters@0
|
79 samplerate = to_Hz( sampstr, 0 ) ;
|
tomwalters@0
|
80 amplitude = atof( astr ) ;
|
tomwalters@0
|
81 offset = atof( ostr ) ;
|
tomwalters@0
|
82
|
tomwalters@0
|
83 if ( ( type = typeindex( typestr ) ) < 0 ) {
|
tomwalters@0
|
84 fprintf( stderr, "tone: bad type [%s]\n", typestr ) ;
|
tomwalters@0
|
85 exit( 1 ) ;
|
tomwalters@0
|
86 }
|
tomwalters@0
|
87
|
tomwalters@0
|
88 n = to_p( dstr, samplerate ) ;
|
tomwalters@0
|
89
|
tomwalters@0
|
90 if ( isstr( perstr, optdflt( option, "period" ) ) )
|
tomwalters@0
|
91 T = 1.0 / to_Hz( freqstr, samplerate ) ;
|
tomwalters@0
|
92 else
|
tomwalters@0
|
93 T = to_s( perstr, samplerate ) ;
|
tomwalters@0
|
94
|
tomwalters@0
|
95 Tr = TWOPI / ( samplerate * T ) ; /* period of max resolution */
|
tomwalters@0
|
96
|
tomwalters@0
|
97 if ( iststr( phasestr, "sine" ) ) /* start */
|
tomwalters@0
|
98 r = 0 ;
|
tomwalters@0
|
99 else if ( iststr( phasestr, "cosine" ) )
|
tomwalters@0
|
100 r = TWOPI / 4 ;
|
tomwalters@0
|
101 else if ( iststr( phasestr, "antisine" ) )
|
tomwalters@0
|
102 r = TWOPI / 2 ;
|
tomwalters@0
|
103 else if ( iststr( phasestr, "anticosine" ) )
|
tomwalters@0
|
104 r = 3 * TWOPI / 4 ;
|
tomwalters@0
|
105 else if ( isstr( phasestr + strlen( phasestr ) - 3, "deg" ) )
|
tomwalters@0
|
106 r = TWOPI * ( atof( phasestr ) / 360. ) ;
|
tomwalters@0
|
107 else
|
tomwalters@0
|
108 r = TWOPI * ( to_s( phasestr, samplerate ) / T ) ;
|
tomwalters@0
|
109
|
tomwalters@0
|
110 for ( i = 0 ; i < n ; i++, r += Tr ) {
|
tomwalters@0
|
111 y = amplitude * sin(r) + offset ;
|
tomwalters@0
|
112 writeitem( &y, type, 1, stdout ) ;
|
tomwalters@0
|
113 }
|
tomwalters@0
|
114 }
|