1 /* Generate a header file for a particular
2 single or double frequency */
11 static float loudness
=16384.0;
13 static int calc_samples(int freq
)
16 /* Calculate the number of samples at 8000hz sampling
17 we need to have this wave form */
19 /* Take out common 2's up to six times */
25 /* Take out common 5's (up to three times */
31 /* No more common factors. */
36 ** This routine converts from linear to ulaw
38 ** Craig Reese: IDA/Supercomputing Research Center
39 ** Joe Campbell: Department of Defense
43 ** 1) CCITT Recommendation G.711 (very difficult to follow)
44 ** 2) "A New Digital Technique for Implementation of Any
45 ** Continuous PCM Companding Law," Villeret, Michel,
46 ** et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
47 ** 1973, pg. 11.12-11.17
48 ** 3) MIL-STD-188-113,"Interoperability and Performance Standards
49 ** for Analog-to_Digital Conversion Techniques,"
52 ** Input: Signed 16 bit linear sample
53 ** Output: 8 bit ulaw sample
56 #define ZEROTRAP /* turn on the trap as per the MIL-STD */
57 #define BIAS 0x84 /* define the add-in bias for 16 bit samples */
60 static unsigned char linear2ulaw(short sample
) {
61 static int exp_lut
[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
62 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
63 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
64 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
65 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
66 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
67 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
68 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
69 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
70 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
71 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
72 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
73 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
74 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
75 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
76 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
77 int sign
, exponent
, mantissa
;
78 unsigned char ulawbyte
;
80 /* Get the sample into sign-magnitude. */
81 sign
= (sample
>> 8) & 0x80; /* set aside the sign */
82 if (sign
!= 0) sample
= -sample
; /* get magnitude */
83 if (sample
> CLIP
) sample
= CLIP
; /* clip the magnitude */
85 /* Convert from 16 bit linear to ulaw. */
86 sample
= sample
+ BIAS
;
87 exponent
= exp_lut
[(sample
>> 7) & 0xFF];
88 mantissa
= (sample
>> (exponent
+ 3)) & 0x0F;
89 ulawbyte
= ~(sign
| (exponent
<< 4) | mantissa
);
91 if (ulawbyte
== 0) ulawbyte
= 0x02; /* optional CCITT trap */
97 int main(int argc
, char *argv
[])
103 int x
, samples1
, samples2
, samples
=0;
106 fprintf(stderr
, "Usage: gensound <name> <freq1> [freq2]\n");
109 freq1
= atoi(argv
[2]);
111 freq2
= atoi(argv
[3]);
114 wlen1
= 8000.0/(float)freq1
;
115 samples1
= calc_samples(freq1
);
116 printf("Wavelength 1 (in samples): %10.5f\n", wlen1
);
117 printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples1
, samples1
/ wlen1
);
119 wlen2
= 8000.0/(float)freq2
;
120 samples2
= calc_samples(freq2
);
121 printf("Wavelength 1 (in samples): %10.5f\n", wlen2
);
122 printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples2
, samples2
/ wlen2
);
126 while(samples
% samples2
)
129 printf("Need %d samples\n", samples
);
130 snprintf(fn
, sizeof(fn
), "%s.h", argv
[1]);
131 if ((f
= fopen(fn
, "w"))) {
133 fprintf(f
, "/* %s: Generated from frequencies %d and %d \n"
134 " by gentone. %d samples */\n", fn
, freq1
, freq2
, samples
);
136 fprintf(f
, "/* %s: Generated from frequency %d\n"
137 " by gentone. %d samples */\n", fn
, freq1
, samples
);
138 fprintf(f
, "static unsigned char %s[%d] = {\n\t", argv
[1], samples
);
139 for (x
=0;x
<samples
;x
++) {
140 val
= loudness
* sin((freq1
* 2.0 * M_PI
* x
)/8000.0);
142 val
+= loudness
* sin((freq2
* 2.0 * M_PI
* x
)/8000.0);
143 fprintf(f
, "%3d, ", (int) linear2ulaw(val
));
151 printf("Wrote %s\n", fn
);
153 fprintf(stderr
, "Unable to open %s for writing\n", fn
);