Libav
|
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 FFmpeg. 00008 * 00009 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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 NB_CHANNELS 2 00028 #define FE 44100 00029 00030 static unsigned int myrnd(unsigned int *seed_ptr, int n) 00031 { 00032 unsigned int seed, val; 00033 00034 seed = *seed_ptr; 00035 seed = (seed * 314159) + 1; 00036 if (n == 256) { 00037 val = seed >> 24; 00038 } else { 00039 val = seed % n; 00040 } 00041 *seed_ptr = seed; 00042 return val; 00043 } 00044 00045 #define FRAC_BITS 16 00046 #define FRAC_ONE (1 << FRAC_BITS) 00047 00048 #define COS_TABLE_BITS 7 00049 00050 /* integer cosinus */ 00051 static const unsigned short cos_table[(1 << COS_TABLE_BITS) + 2] = { 00052 0x8000, 0x7ffe, 0x7ff6, 0x7fea, 0x7fd9, 0x7fc2, 0x7fa7, 0x7f87, 00053 0x7f62, 0x7f38, 0x7f0a, 0x7ed6, 0x7e9d, 0x7e60, 0x7e1e, 0x7dd6, 00054 0x7d8a, 0x7d3a, 0x7ce4, 0x7c89, 0x7c2a, 0x7bc6, 0x7b5d, 0x7aef, 00055 0x7a7d, 0x7a06, 0x798a, 0x790a, 0x7885, 0x77fb, 0x776c, 0x76d9, 00056 0x7642, 0x75a6, 0x7505, 0x7460, 0x73b6, 0x7308, 0x7255, 0x719e, 00057 0x70e3, 0x7023, 0x6f5f, 0x6e97, 0x6dca, 0x6cf9, 0x6c24, 0x6b4b, 00058 0x6a6e, 0x698c, 0x68a7, 0x67bd, 0x66d0, 0x65de, 0x64e9, 0x63ef, 00059 0x62f2, 0x61f1, 0x60ec, 0x5fe4, 0x5ed7, 0x5dc8, 0x5cb4, 0x5b9d, 00060 0x5a82, 0x5964, 0x5843, 0x571e, 0x55f6, 0x54ca, 0x539b, 0x5269, 00061 0x5134, 0x4ffb, 0x4ec0, 0x4d81, 0x4c40, 0x4afb, 0x49b4, 0x486a, 00062 0x471d, 0x45cd, 0x447b, 0x4326, 0x41ce, 0x4074, 0x3f17, 0x3db8, 00063 0x3c57, 0x3af3, 0x398d, 0x3825, 0x36ba, 0x354e, 0x33df, 0x326e, 00064 0x30fc, 0x2f87, 0x2e11, 0x2c99, 0x2b1f, 0x29a4, 0x2827, 0x26a8, 00065 0x2528, 0x23a7, 0x2224, 0x209f, 0x1f1a, 0x1d93, 0x1c0c, 0x1a83, 00066 0x18f9, 0x176e, 0x15e2, 0x1455, 0x12c8, 0x113a, 0x0fab, 0x0e1c, 00067 0x0c8c, 0x0afb, 0x096b, 0x07d9, 0x0648, 0x04b6, 0x0324, 0x0192, 00068 0x0000, 0x0000, 00069 }; 00070 00071 #define CSHIFT (FRAC_BITS - COS_TABLE_BITS - 2) 00072 00073 static int int_cos(int a) 00074 { 00075 int neg, v, f; 00076 const unsigned short *p; 00077 00078 a = a & (FRAC_ONE - 1); /* modulo 2 * pi */ 00079 if (a >= (FRAC_ONE / 2)) 00080 a = FRAC_ONE - a; 00081 neg = 0; 00082 if (a > (FRAC_ONE / 4)) { 00083 neg = -1; 00084 a = (FRAC_ONE / 2) - a; 00085 } 00086 p = cos_table + (a >> CSHIFT); 00087 /* linear interpolation */ 00088 f = a & ((1 << CSHIFT) - 1); 00089 v = p[0] + (((p[1] - p[0]) * f + (1 << (CSHIFT - 1))) >> CSHIFT); 00090 v = (v ^ neg) - neg; 00091 v = v << (FRAC_BITS - 15); 00092 return v; 00093 } 00094 00095 FILE *outfile; 00096 00097 static void put_sample(int v) 00098 { 00099 fputc(v & 0xff, outfile); 00100 fputc((v >> 8) & 0xff, outfile); 00101 } 00102 00103 int main(int argc, char **argv) 00104 { 00105 int i, a, v, j, f, amp, ampa; 00106 unsigned int seed = 1; 00107 int tabf1[NB_CHANNELS], tabf2[NB_CHANNELS]; 00108 int taba[NB_CHANNELS]; 00109 00110 if (argc != 2) { 00111 printf("usage: %s file\n" 00112 "generate a test raw 16 bit stereo audio stream\n", argv[0]); 00113 exit(1); 00114 } 00115 00116 outfile = fopen(argv[1], "wb"); 00117 if (!outfile) { 00118 perror(argv[1]); 00119 return 1; 00120 } 00121 00122 /* 1 second of single freq sinus at 1000 Hz */ 00123 a = 0; 00124 for(i=0;i<1 * FE;i++) { 00125 v = (int_cos(a) * 10000) >> FRAC_BITS; 00126 for(j=0;j<NB_CHANNELS;j++) 00127 put_sample(v); 00128 a += (1000 * FRAC_ONE) / FE; 00129 } 00130 00131 /* 1 second of varing frequency between 100 and 10000 Hz */ 00132 a = 0; 00133 for(i=0;i<1 * FE;i++) { 00134 v = (int_cos(a) * 10000) >> FRAC_BITS; 00135 for(j=0;j<NB_CHANNELS;j++) 00136 put_sample(v); 00137 f = 100 + (((10000 - 100) * i) / FE); 00138 a += (f * FRAC_ONE) / FE; 00139 } 00140 00141 /* 0.5 second of low amplitude white noise */ 00142 for(i=0;i<FE / 2;i++) { 00143 v = myrnd(&seed, 20000) - 10000; 00144 for(j=0;j<NB_CHANNELS;j++) 00145 put_sample(v); 00146 } 00147 00148 /* 0.5 second of high amplitude white noise */ 00149 for(i=0;i<FE / 2;i++) { 00150 v = myrnd(&seed, 65535) - 32768; 00151 for(j=0;j<NB_CHANNELS;j++) 00152 put_sample(v); 00153 } 00154 00155 /* stereo : 2 unrelated ramps */ 00156 for(j=0;j<NB_CHANNELS;j++) { 00157 taba[j] = 0; 00158 tabf1[j] = 100 + myrnd(&seed, 5000); 00159 tabf2[j] = 100 + myrnd(&seed, 5000); 00160 } 00161 for(i=0;i<1 * FE;i++) { 00162 for(j=0;j<NB_CHANNELS;j++) { 00163 v = (int_cos(taba[j]) * 10000) >> FRAC_BITS; 00164 put_sample(v); 00165 f = tabf1[j] + (((tabf2[j] - tabf1[j]) * i) / FE); 00166 taba[j] += (f * FRAC_ONE) / FE; 00167 } 00168 } 00169 00170 /* stereo 500 Hz with varying volume */ 00171 a = 0; 00172 ampa = 0; 00173 for(i=0;i<2 * FE;i++) { 00174 for(j=0;j<NB_CHANNELS;j++) { 00175 amp = ((FRAC_ONE + int_cos(ampa)) * 5000) >> FRAC_BITS; 00176 if (j & 1) 00177 amp = 10000 - amp; 00178 v = (int_cos(a) * amp) >> FRAC_BITS; 00179 put_sample(v); 00180 a += (500 * FRAC_ONE) / FE; 00181 ampa += (2 * FRAC_ONE) / FE; 00182 } 00183 } 00184 00185 fclose(outfile); 00186 return 0; 00187 }