00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdlib.h>
00025 #include <stdint.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028
00029 #define MAX_CHANNELS 8
00030
00031 static unsigned int myrnd(unsigned int *seed_ptr, int n)
00032 {
00033 unsigned int seed, val;
00034
00035 seed = *seed_ptr;
00036 seed = (seed * 314159) + 1;
00037 if (n == 256) {
00038 val = seed >> 24;
00039 } else {
00040 val = seed % n;
00041 }
00042 *seed_ptr = seed;
00043 return val;
00044 }
00045
00046 #define FRAC_BITS 16
00047 #define FRAC_ONE (1 << FRAC_BITS)
00048
00049 #define COS_TABLE_BITS 7
00050
00051
00052 static const unsigned short cos_table[(1 << COS_TABLE_BITS) + 2] = {
00053 0x8000, 0x7ffe, 0x7ff6, 0x7fea, 0x7fd9, 0x7fc2, 0x7fa7, 0x7f87,
00054 0x7f62, 0x7f38, 0x7f0a, 0x7ed6, 0x7e9d, 0x7e60, 0x7e1e, 0x7dd6,
00055 0x7d8a, 0x7d3a, 0x7ce4, 0x7c89, 0x7c2a, 0x7bc6, 0x7b5d, 0x7aef,
00056 0x7a7d, 0x7a06, 0x798a, 0x790a, 0x7885, 0x77fb, 0x776c, 0x76d9,
00057 0x7642, 0x75a6, 0x7505, 0x7460, 0x73b6, 0x7308, 0x7255, 0x719e,
00058 0x70e3, 0x7023, 0x6f5f, 0x6e97, 0x6dca, 0x6cf9, 0x6c24, 0x6b4b,
00059 0x6a6e, 0x698c, 0x68a7, 0x67bd, 0x66d0, 0x65de, 0x64e9, 0x63ef,
00060 0x62f2, 0x61f1, 0x60ec, 0x5fe4, 0x5ed7, 0x5dc8, 0x5cb4, 0x5b9d,
00061 0x5a82, 0x5964, 0x5843, 0x571e, 0x55f6, 0x54ca, 0x539b, 0x5269,
00062 0x5134, 0x4ffb, 0x4ec0, 0x4d81, 0x4c40, 0x4afb, 0x49b4, 0x486a,
00063 0x471d, 0x45cd, 0x447b, 0x4326, 0x41ce, 0x4074, 0x3f17, 0x3db8,
00064 0x3c57, 0x3af3, 0x398d, 0x3825, 0x36ba, 0x354e, 0x33df, 0x326e,
00065 0x30fc, 0x2f87, 0x2e11, 0x2c99, 0x2b1f, 0x29a4, 0x2827, 0x26a8,
00066 0x2528, 0x23a7, 0x2224, 0x209f, 0x1f1a, 0x1d93, 0x1c0c, 0x1a83,
00067 0x18f9, 0x176e, 0x15e2, 0x1455, 0x12c8, 0x113a, 0x0fab, 0x0e1c,
00068 0x0c8c, 0x0afb, 0x096b, 0x07d9, 0x0648, 0x04b6, 0x0324, 0x0192,
00069 0x0000, 0x0000,
00070 };
00071
00072 #define CSHIFT (FRAC_BITS - COS_TABLE_BITS - 2)
00073
00074 static int int_cos(int a)
00075 {
00076 int neg, v, f;
00077 const unsigned short *p;
00078
00079 a = a & (FRAC_ONE - 1);
00080 if (a >= (FRAC_ONE / 2))
00081 a = FRAC_ONE - a;
00082 neg = 0;
00083 if (a > (FRAC_ONE / 4)) {
00084 neg = -1;
00085 a = (FRAC_ONE / 2) - a;
00086 }
00087 p = cos_table + (a >> CSHIFT);
00088
00089 f = a & ((1 << CSHIFT) - 1);
00090 v = p[0] + (((p[1] - p[0]) * f + (1 << (CSHIFT - 1))) >> CSHIFT);
00091 v = (v ^ neg) - neg;
00092 v = v << (FRAC_BITS - 15);
00093 return v;
00094 }
00095
00096 FILE *outfile;
00097
00098 static void put16(int16_t v)
00099 {
00100 fputc( v & 0xff, outfile);
00101 fputc((v >> 8) & 0xff, outfile);
00102 }
00103
00104 static void put32(uint32_t v)
00105 {
00106 fputc( v & 0xff, outfile);
00107 fputc((v >> 8) & 0xff, outfile);
00108 fputc((v >> 16) & 0xff, outfile);
00109 fputc((v >> 24) & 0xff, outfile);
00110 }
00111
00112 #define HEADER_SIZE 46
00113 #define FMT_SIZE 18
00114 #define SAMPLE_SIZE 2
00115 #define WFORMAT_PCM 0x0001
00116
00117 static void put_wav_header(int sample_rate, int channels, int nb_samples)
00118 {
00119 int block_align = SAMPLE_SIZE * channels;
00120 int data_size = block_align * nb_samples;
00121
00122 fputs("RIFF", outfile);
00123 put32(HEADER_SIZE + data_size);
00124 fputs("WAVEfmt ", outfile);
00125 put32(FMT_SIZE);
00126 put16(WFORMAT_PCM);
00127 put16(channels);
00128 put32(sample_rate);
00129 put32(block_align * sample_rate);
00130 put16(block_align);
00131 put16(SAMPLE_SIZE * 8);
00132 put16(0);
00133 fputs("data", outfile);
00134 put32(data_size);
00135 }
00136
00137 int main(int argc, char **argv)
00138 {
00139 int i, a, v, j, f, amp, ampa;
00140 unsigned int seed = 1;
00141 int tabf1[MAX_CHANNELS], tabf2[MAX_CHANNELS];
00142 int taba[MAX_CHANNELS];
00143 int sample_rate = 44100;
00144 int nb_channels = 2;
00145 char *ext;
00146
00147 if (argc < 2 || argc > 5) {
00148 printf("usage: %s file [<sample rate> [<channels>] [<random seed>]]\n"
00149 "generate a test raw 16 bit audio stream\n"
00150 "If the file extension is .wav a WAVE header will be added.\n"
00151 "default: 44100 Hz stereo\n", argv[0]);
00152 exit(1);
00153 }
00154
00155 if (argc > 2) {
00156 sample_rate = atoi(argv[2]);
00157 if (sample_rate <= 0) {
00158 fprintf(stderr, "invalid sample rate: %d\n", sample_rate);
00159 return 1;
00160 }
00161 }
00162
00163 if (argc > 3) {
00164 nb_channels = atoi(argv[3]);
00165 if (nb_channels < 1 || nb_channels > MAX_CHANNELS) {
00166 fprintf(stderr, "invalid number of channels: %d\n", nb_channels);
00167 return 1;
00168 }
00169 }
00170
00171 if (argc > 4)
00172 seed = atoi(argv[4]);
00173
00174 outfile = fopen(argv[1], "wb");
00175 if (!outfile) {
00176 perror(argv[1]);
00177 return 1;
00178 }
00179
00180 if ((ext = strrchr(argv[1], '.')) != NULL && !strcmp(ext, ".wav"))
00181 put_wav_header(sample_rate, nb_channels, 6 * sample_rate);
00182
00183
00184 a = 0;
00185 for (i = 0; i < 1 * sample_rate; i++) {
00186 v = (int_cos(a) * 10000) >> FRAC_BITS;
00187 for (j = 0; j < nb_channels; j++)
00188 put16(v);
00189 a += (1000 * FRAC_ONE) / sample_rate;
00190 }
00191
00192
00193 a = 0;
00194 for (i = 0; i < 1 * sample_rate; i++) {
00195 v = (int_cos(a) * 10000) >> FRAC_BITS;
00196 for (j = 0; j < nb_channels; j++)
00197 put16(v);
00198 f = 100 + (((10000 - 100) * i) / sample_rate);
00199 a += (f * FRAC_ONE) / sample_rate;
00200 }
00201
00202
00203 for (i = 0; i < sample_rate / 2; i++) {
00204 v = myrnd(&seed, 20000) - 10000;
00205 for (j = 0; j < nb_channels; j++)
00206 put16(v);
00207 }
00208
00209
00210 for (i = 0; i < sample_rate / 2; i++) {
00211 v = myrnd(&seed, 65535) - 32768;
00212 for (j = 0; j < nb_channels; j++)
00213 put16(v);
00214 }
00215
00216
00217 for (j = 0; j < nb_channels; j++) {
00218 taba[j] = 0;
00219 tabf1[j] = 100 + myrnd(&seed, 5000);
00220 tabf2[j] = 100 + myrnd(&seed, 5000);
00221 }
00222 for (i = 0; i < 1 * sample_rate; i++) {
00223 for (j = 0; j < nb_channels; j++) {
00224 v = (int_cos(taba[j]) * 10000) >> FRAC_BITS;
00225 put16(v);
00226 f = tabf1[j] + (((tabf2[j] - tabf1[j]) * i) / sample_rate);
00227 taba[j] += (f * FRAC_ONE) / sample_rate;
00228 }
00229 }
00230
00231
00232 a = 0;
00233 ampa = 0;
00234 for (i = 0; i < 2 * sample_rate; i++) {
00235 for (j = 0; j < nb_channels; j++) {
00236 amp = ((FRAC_ONE + int_cos(ampa)) * 5000) >> FRAC_BITS;
00237 if (j & 1)
00238 amp = 10000 - amp;
00239 v = (int_cos(a) * amp) >> FRAC_BITS;
00240 put16(v);
00241 a += (500 * FRAC_ONE) / sample_rate;
00242 ampa += (2 * FRAC_ONE) / sample_rate;
00243 }
00244 }
00245
00246 fclose(outfile);
00247 return 0;
00248 }