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 > 4) {
00148 printf("usage: %s file [<sample rate> [<channels>]]\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 outfile = fopen(argv[1], "wb");
00172 if (!outfile) {
00173 perror(argv[1]);
00174 return 1;
00175 }
00176
00177 if ((ext = strrchr(argv[1], '.')) != NULL && !strcmp(ext, ".wav"))
00178 put_wav_header(sample_rate, nb_channels, 6 * sample_rate);
00179
00180
00181 a = 0;
00182 for (i = 0; i < 1 * sample_rate; i++) {
00183 v = (int_cos(a) * 10000) >> FRAC_BITS;
00184 for (j = 0; j < nb_channels; j++)
00185 put16(v);
00186 a += (1000 * FRAC_ONE) / sample_rate;
00187 }
00188
00189
00190 a = 0;
00191 for (i = 0; i < 1 * sample_rate; i++) {
00192 v = (int_cos(a) * 10000) >> FRAC_BITS;
00193 for (j = 0; j < nb_channels; j++)
00194 put16(v);
00195 f = 100 + (((10000 - 100) * i) / sample_rate);
00196 a += (f * FRAC_ONE) / sample_rate;
00197 }
00198
00199
00200 for (i = 0; i < sample_rate / 2; i++) {
00201 v = myrnd(&seed, 20000) - 10000;
00202 for (j = 0; j < nb_channels; j++)
00203 put16(v);
00204 }
00205
00206
00207 for (i = 0; i < sample_rate / 2; i++) {
00208 v = myrnd(&seed, 65535) - 32768;
00209 for (j = 0; j < nb_channels; j++)
00210 put16(v);
00211 }
00212
00213
00214 for (j = 0; j < nb_channels; j++) {
00215 taba[j] = 0;
00216 tabf1[j] = 100 + myrnd(&seed, 5000);
00217 tabf2[j] = 100 + myrnd(&seed, 5000);
00218 }
00219 for (i = 0; i < 1 * sample_rate; i++) {
00220 for (j = 0; j < nb_channels; j++) {
00221 v = (int_cos(taba[j]) * 10000) >> FRAC_BITS;
00222 put16(v);
00223 f = tabf1[j] + (((tabf2[j] - tabf1[j]) * i) / sample_rate);
00224 taba[j] += (f * FRAC_ONE) / sample_rate;
00225 }
00226 }
00227
00228
00229 a = 0;
00230 ampa = 0;
00231 for (i = 0; i < 2 * sample_rate; i++) {
00232 for (j = 0; j < nb_channels; j++) {
00233 amp = ((FRAC_ONE + int_cos(ampa)) * 5000) >> FRAC_BITS;
00234 if (j & 1)
00235 amp = 10000 - amp;
00236 v = (int_cos(a) * amp) >> FRAC_BITS;
00237 put16(v);
00238 a += (500 * FRAC_ONE) / sample_rate;
00239 ampa += (2 * FRAC_ONE) / sample_rate;
00240 }
00241 }
00242
00243 fclose(outfile);
00244 return 0;
00245 }