00001
00002
00003
00004 #include <stdio.h>
00005 #include <math.h>
00006 #include <string.h>
00007 #include <unistd.h>
00008 #include <stdlib.h>
00009 #define CLIP 32635
00010 #define BIAS 0x84
00011 static float loudness=16384.0;
00012
00013 static int calc_samples(int freq)
00014 {
00015 int x, samples;
00016
00017
00018 samples = 8000;
00019
00020 for (x=0;x<6;x++)
00021 if (!(freq % 2)) {
00022 freq /= 2;
00023 samples /= 2;
00024 }
00025
00026 for (x=0;x<3;x++)
00027 if (!(freq % 5)) {
00028 freq /= 5;
00029 samples /=5;
00030 }
00031
00032 return samples;
00033 }
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 #define ZEROTRAP
00057 #define BIAS 0x84
00058 #define CLIP 32635
00059
00060 static unsigned char linear2ulaw(short sample) {
00061 static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00062 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00063 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00064 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00065 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00066 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00067 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00068 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00069 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00070 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00071 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00072 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00073 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00074 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00075 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00076 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
00077 int sign, exponent, mantissa;
00078 unsigned char ulawbyte;
00079
00080
00081 sign = (sample >> 8) & 0x80;
00082 if (sign != 0) sample = -sample;
00083 if (sample > CLIP) sample = CLIP;
00084
00085
00086 sample = sample + BIAS;
00087 exponent = exp_lut[(sample >> 7) & 0xFF];
00088 mantissa = (sample >> (exponent + 3)) & 0x0F;
00089 ulawbyte = ~(sign | (exponent << 4) | mantissa);
00090 #ifdef ZEROTRAP
00091 if (ulawbyte == 0) ulawbyte = 0x02;
00092 #endif
00093
00094 return(ulawbyte);
00095 }
00096
00097 int main(int argc, char *argv[])
00098 {
00099 FILE *f;
00100 int freq1, freq2;
00101 float wlen1, wlen2;
00102 float val;
00103 int x, samples1, samples2, samples=0;
00104 char fn[256];
00105 if (argc < 3) {
00106 fprintf(stderr, "Usage: gensound <name> <freq1> [freq2]\n");
00107 exit(1);
00108 }
00109 freq1 = atoi(argv[2]);
00110 if (argc > 3)
00111 freq2 = atoi(argv[3]);
00112 else
00113 freq2 = 0;
00114 wlen1 = 8000.0/(float)freq1;
00115 samples1 = calc_samples(freq1);
00116 printf("Wavelength 1 (in samples): %10.5f\n", wlen1);
00117 printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples1, samples1 / wlen1);
00118 if (freq2) {
00119 wlen2 = 8000.0/(float)freq2;
00120 samples2 = calc_samples(freq2);
00121 printf("Wavelength 1 (in samples): %10.5f\n", wlen2);
00122 printf("Minimum samples (1): %d (%f.3 wavelengths)\n", samples2, samples2 / wlen2);
00123 }
00124 samples = samples1;
00125 if (freq2) {
00126 while(samples % samples2)
00127 samples += samples1;
00128 }
00129 printf("Need %d samples\n", samples);
00130 snprintf(fn, sizeof(fn), "%s.h", argv[1]);
00131 if ((f = fopen(fn, "w"))) {
00132 if (freq2)
00133 fprintf(f, "/* %s: Generated from frequencies %d and %d \n"
00134 " by gentone. %d samples */\n", fn, freq1, freq2, samples);
00135 else
00136 fprintf(f, "/* %s: Generated from frequency %d\n"
00137 " by gentone. %d samples */\n", fn, freq1, samples);
00138 fprintf(f, "static unsigned char %s[%d] = {\n\t", argv[1], samples);
00139 for (x=0;x<samples;x++) {
00140 val = loudness * sin((freq1 * 2.0 * M_PI * x)/8000.0);
00141 if (freq2)
00142 val += loudness * sin((freq2 * 2.0 * M_PI * x)/8000.0);
00143 fprintf(f, "%3d, ", (int) linear2ulaw(val));
00144 if (!((x+1) % 8))
00145 fprintf(f, "\n\t");
00146 }
00147 if (x % 15)
00148 fprintf(f, "\n");
00149 fprintf(f, "};\n");
00150 fclose(f);
00151 printf("Wrote %s\n", fn);
00152 } else {
00153 fprintf(stderr, "Unable to open %s for writing\n", fn);
00154 return 1;
00155 }
00156 return 0;
00157 }