Libav 0.7.1
|
00001 /* 00002 * Generates a synthetic stereo sound 00003 * NOTE: No floats are used to guarantee a bit exact output. 00004 * 00005 * Copyright (c) 2002 Fabrice Bellard 00006 * 00007 * This file is part of Libav. 00008 * 00009 * Libav is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU Lesser General Public 00011 * License as published by the Free Software Foundation; either 00012 * version 2.1 of the License, or (at your option) any later version. 00013 * 00014 * Libav is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * Lesser General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU Lesser General Public 00020 * License along with Libav; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 */ 00023 00024 #include <stdlib.h> 00025 #include <stdio.h> 00026 00027 #define MAX_CHANNELS 8 00028 00029 static unsigned int myrnd(unsigned int *seed_ptr, int n) 00030 { 00031 unsigned int seed, val; 00032 00033 seed = *seed_ptr; 00034 seed = (seed * 314159) + 1; 00035 if (n == 256) { 00036 val = seed >> 24; 00037 } else { 00038 val = seed % n; 00039 } 00040 *seed_ptr = seed; 00041 return val; 00042 } 00043 00044 #define FRAC_BITS 16 00045 #define FRAC_ONE (1 << FRAC_BITS) 00046 00047 #define COS_TABLE_BITS 7 00048 00049 /* integer cosinus */ 00050 static const unsigned short cos_table[(1 << COS_TABLE_BITS) + 2] = { 00051 0x8000, 0x7ffe, 0x7ff6, 0x7fea, 0x7fd9, 0x7fc2, 0x7fa7, 0x7f87, 00052 0x7f62, 0x7f38, 0x7f0a, 0x7ed6, 0x7e9d, 0x7e60, 0x7e1e, 0x7dd6, 00053 0x7d8a, 0x7d3a, 0x7ce4, 0x7c89, 0x7c2a, 0x7bc6, 0x7b5d, 0x7aef, 00054 0x7a7d, 0x7a06, 0x798a, 0x790a, 0x7885, 0x77fb, 0x776c, 0x76d9, 00055 0x7642, 0x75a6, 0x7505, 0x7460, 0x73b6, 0x7308, 0x7255, 0x719e, 00056 0x70e3, 0x7023, 0x6f5f, 0x6e97, 0x6dca, 0x6cf9, 0x6c24, 0x6b4b, 00057 0x6a6e, 0x698c, 0x68a7, 0x67bd, 0x66d0, 0x65de, 0x64e9, 0x63ef, 00058 0x62f2, 0x61f1, 0x60ec, 0x5fe4, 0x5ed7, 0x5dc8, 0x5cb4, 0x5b9d, 00059 0x5a82, 0x5964, 0x5843, 0x571e, 0x55f6, 0x54ca, 0x539b, 0x5269, 00060 0x5134, 0x4ffb, 0x4ec0, 0x4d81, 0x4c40, 0x4afb, 0x49b4, 0x486a, 00061 0x471d, 0x45cd, 0x447b, 0x4326, 0x41ce, 0x4074, 0x3f17, 0x3db8, 00062 0x3c57, 0x3af3, 0x398d, 0x3825, 0x36ba, 0x354e, 0x33df, 0x326e, 00063 0x30fc, 0x2f87, 0x2e11, 0x2c99, 0x2b1f, 0x29a4, 0x2827, 0x26a8, 00064 0x2528, 0x23a7, 0x2224, 0x209f, 0x1f1a, 0x1d93, 0x1c0c, 0x1a83, 00065 0x18f9, 0x176e, 0x15e2, 0x1455, 0x12c8, 0x113a, 0x0fab, 0x0e1c, 00066 0x0c8c, 0x0afb, 0x096b, 0x07d9, 0x0648, 0x04b6, 0x0324, 0x0192, 00067 0x0000, 0x0000, 00068 }; 00069 00070 #define CSHIFT (FRAC_BITS - COS_TABLE_BITS - 2) 00071 00072 static int int_cos(int a) 00073 { 00074 int neg, v, f; 00075 const unsigned short *p; 00076 00077 a = a & (FRAC_ONE - 1); /* modulo 2 * pi */ 00078 if (a >= (FRAC_ONE / 2)) 00079 a = FRAC_ONE - a; 00080 neg = 0; 00081 if (a > (FRAC_ONE / 4)) { 00082 neg = -1; 00083 a = (FRAC_ONE / 2) - a; 00084 } 00085 p = cos_table + (a >> CSHIFT); 00086 /* linear interpolation */ 00087 f = a & ((1 << CSHIFT) - 1); 00088 v = p[0] + (((p[1] - p[0]) * f + (1 << (CSHIFT - 1))) >> CSHIFT); 00089 v = (v ^ neg) - neg; 00090 v = v << (FRAC_BITS - 15); 00091 return v; 00092 } 00093 00094 FILE *outfile; 00095 00096 static void put_sample(int v) 00097 { 00098 fputc(v & 0xff, outfile); 00099 fputc((v >> 8) & 0xff, outfile); 00100 } 00101 00102 int main(int argc, char **argv) 00103 { 00104 int i, a, v, j, f, amp, ampa; 00105 unsigned int seed = 1; 00106 int tabf1[MAX_CHANNELS], tabf2[MAX_CHANNELS]; 00107 int taba[MAX_CHANNELS]; 00108 int sample_rate = 44100; 00109 int nb_channels = 2; 00110 00111 if (argc < 2 || argc > 4) { 00112 printf("usage: %s file [<sample rate> [<channels>]]\n" 00113 "generate a test raw 16 bit audio stream\n" 00114 "default: 44100 Hz stereo\n", argv[0]); 00115 exit(1); 00116 } 00117 00118 if (argc > 2) { 00119 sample_rate = atoi(argv[2]); 00120 if (sample_rate <= 0) { 00121 fprintf(stderr, "invalid sample rate: %d\n", sample_rate); 00122 return 1; 00123 } 00124 } 00125 00126 if (argc > 3) { 00127 nb_channels = atoi(argv[3]); 00128 if (nb_channels < 1 || nb_channels > MAX_CHANNELS) { 00129 fprintf(stderr, "invalid number of channels: %d\n", nb_channels); 00130 return 1; 00131 } 00132 } 00133 00134 outfile = fopen(argv[1], "wb"); 00135 if (!outfile) { 00136 perror(argv[1]); 00137 return 1; 00138 } 00139 00140 /* 1 second of single freq sinus at 1000 Hz */ 00141 a = 0; 00142 for(i=0;i<1 * sample_rate;i++) { 00143 v = (int_cos(a) * 10000) >> FRAC_BITS; 00144 for(j=0;j<nb_channels;j++) 00145 put_sample(v); 00146 a += (1000 * FRAC_ONE) / sample_rate; 00147 } 00148 00149 /* 1 second of varing frequency between 100 and 10000 Hz */ 00150 a = 0; 00151 for(i=0;i<1 * sample_rate;i++) { 00152 v = (int_cos(a) * 10000) >> FRAC_BITS; 00153 for(j=0;j<nb_channels;j++) 00154 put_sample(v); 00155 f = 100 + (((10000 - 100) * i) / sample_rate); 00156 a += (f * FRAC_ONE) / sample_rate; 00157 } 00158 00159 /* 0.5 second of low amplitude white noise */ 00160 for(i=0;i<sample_rate / 2;i++) { 00161 v = myrnd(&seed, 20000) - 10000; 00162 for(j=0;j<nb_channels;j++) 00163 put_sample(v); 00164 } 00165 00166 /* 0.5 second of high amplitude white noise */ 00167 for(i=0;i<sample_rate / 2;i++) { 00168 v = myrnd(&seed, 65535) - 32768; 00169 for(j=0;j<nb_channels;j++) 00170 put_sample(v); 00171 } 00172 00173 /* 1 second of unrelated ramps for each channel */ 00174 for(j=0;j<nb_channels;j++) { 00175 taba[j] = 0; 00176 tabf1[j] = 100 + myrnd(&seed, 5000); 00177 tabf2[j] = 100 + myrnd(&seed, 5000); 00178 } 00179 for(i=0;i<1 * sample_rate;i++) { 00180 for(j=0;j<nb_channels;j++) { 00181 v = (int_cos(taba[j]) * 10000) >> FRAC_BITS; 00182 put_sample(v); 00183 f = tabf1[j] + (((tabf2[j] - tabf1[j]) * i) / sample_rate); 00184 taba[j] += (f * FRAC_ONE) / sample_rate; 00185 } 00186 } 00187 00188 /* 2 seconds of 500 Hz with varying volume */ 00189 a = 0; 00190 ampa = 0; 00191 for(i=0;i<2 * sample_rate;i++) { 00192 for(j=0;j<nb_channels;j++) { 00193 amp = ((FRAC_ONE + int_cos(ampa)) * 5000) >> FRAC_BITS; 00194 if (j & 1) 00195 amp = 10000 - amp; 00196 v = (int_cos(a) * amp) >> FRAC_BITS; 00197 put_sample(v); 00198 a += (500 * FRAC_ONE) / sample_rate; 00199 ampa += (2 * FRAC_ONE) / sample_rate; 00200 } 00201 } 00202 00203 fclose(outfile); 00204 return 0; 00205 }