• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

tests/audiogen.c

Go to the documentation of this file.
00001 /*
00002  * Generate a synthetic stereo sound.
00003  * NOTE: No floats are used to guarantee bitexact 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 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 }
Generated on Fri Feb 1 2013 14:34:57 for FFmpeg by doxygen 1.7.1