/*
 * Generate a synthetic stereo sound.
 * NOTE: No floats are used to guarantee bitexact output.
 *
 * Copyright (c) 2002 Fabrice Bellard
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#define MAX_CHANNELS 12

static unsigned int myrnd(unsigned int *seed_ptr, int n)
{
    unsigned int seed, val;

    seed = *seed_ptr;
    seed = (seed * 314159) + 1;
    if (n == 256) {
        val = seed >> 24;
    } else {
        val = seed % n;
    }
    *seed_ptr = seed;
    return val;
}

#define FRAC_BITS 16
#define FRAC_ONE (1 << FRAC_BITS)

#define COS_TABLE_BITS 7

/* integer cosine */
static const unsigned short cos_table[(1 << COS_TABLE_BITS) + 2] = {
    0x8000, 0x7ffe, 0x7ff6, 0x7fea, 0x7fd9, 0x7fc2, 0x7fa7, 0x7f87,
    0x7f62, 0x7f38, 0x7f0a, 0x7ed6, 0x7e9d, 0x7e60, 0x7e1e, 0x7dd6,
    0x7d8a, 0x7d3a, 0x7ce4, 0x7c89, 0x7c2a, 0x7bc6, 0x7b5d, 0x7aef,
    0x7a7d, 0x7a06, 0x798a, 0x790a, 0x7885, 0x77fb, 0x776c, 0x76d9,
    0x7642, 0x75a6, 0x7505, 0x7460, 0x73b6, 0x7308, 0x7255, 0x719e,
    0x70e3, 0x7023, 0x6f5f, 0x6e97, 0x6dca, 0x6cf9, 0x6c24, 0x6b4b,
    0x6a6e, 0x698c, 0x68a7, 0x67bd, 0x66d0, 0x65de, 0x64e9, 0x63ef,
    0x62f2, 0x61f1, 0x60ec, 0x5fe4, 0x5ed7, 0x5dc8, 0x5cb4, 0x5b9d,
    0x5a82, 0x5964, 0x5843, 0x571e, 0x55f6, 0x54ca, 0x539b, 0x5269,
    0x5134, 0x4ffb, 0x4ec0, 0x4d81, 0x4c40, 0x4afb, 0x49b4, 0x486a,
    0x471d, 0x45cd, 0x447b, 0x4326, 0x41ce, 0x4074, 0x3f17, 0x3db8,
    0x3c57, 0x3af3, 0x398d, 0x3825, 0x36ba, 0x354e, 0x33df, 0x326e,
    0x30fc, 0x2f87, 0x2e11, 0x2c99, 0x2b1f, 0x29a4, 0x2827, 0x26a8,
    0x2528, 0x23a7, 0x2224, 0x209f, 0x1f1a, 0x1d93, 0x1c0c, 0x1a83,
    0x18f9, 0x176e, 0x15e2, 0x1455, 0x12c8, 0x113a, 0x0fab, 0x0e1c,
    0x0c8c, 0x0afb, 0x096b, 0x07d9, 0x0648, 0x04b6, 0x0324, 0x0192,
    0x0000, 0x0000,
};

#define CSHIFT (FRAC_BITS - COS_TABLE_BITS - 2)

static int int_cos(int a)
{
    int neg, v, f;
    const unsigned short *p;

    a = a & (FRAC_ONE - 1); /* modulo 2 * pi */
    if (a >= (FRAC_ONE / 2))
        a = FRAC_ONE - a;
    neg = 0;
    if (a > (FRAC_ONE / 4)) {
        neg = -1;
        a   = (FRAC_ONE / 2) - a;
    }
    p = cos_table + (a >> CSHIFT);
    /* linear interpolation */
    f = a & ((1 << CSHIFT) - 1);
    v = p[0] + (((p[1] - p[0]) * f + (1 << (CSHIFT - 1))) >> CSHIFT);
    v = (v ^ neg) - neg;
    v = v << (FRAC_BITS - 15);
    return v;
}

FILE *outfile;

static void put16(int16_t v)
{
    fputc( v       & 0xff, outfile);
    fputc((v >> 8) & 0xff, outfile);
}

static void put32(uint32_t v)
{
    fputc( v        & 0xff, outfile);
    fputc((v >>  8) & 0xff, outfile);
    fputc((v >> 16) & 0xff, outfile);
    fputc((v >> 24) & 0xff, outfile);
}

#define HEADER_SIZE      46
#define FMT_SIZE         18
#define SAMPLE_SIZE       2
#define WFORMAT_PCM  0x0001

static void put_wav_header(int sample_rate, int channels, int nb_samples)
{
    int block_align = SAMPLE_SIZE * channels;
    int data_size   = block_align * nb_samples;

    fputs("RIFF", outfile);
    put32(HEADER_SIZE + data_size);
    fputs("WAVEfmt ", outfile);
    put32(FMT_SIZE);
    put16(WFORMAT_PCM);
    put16(channels);
    put32(sample_rate);
    put32(block_align * sample_rate);
    put16(block_align);
    put16(SAMPLE_SIZE * 8);
    put16(0);
    fputs("data", outfile);
    put32(data_size);
}

int main(int argc, char **argv)
{
    int i, a, v, j, f, amp, ampa;
    unsigned int seed = 1;
    int tabf1[MAX_CHANNELS], tabf2[MAX_CHANNELS];
    int taba[MAX_CHANNELS];
    int sample_rate = 44100;
    int nb_channels = 2;
    char *ext;

    if (argc < 2 || argc > 5) {
        printf("usage: %s file [<sample rate> [<channels>] [<random seed>]]\n"
               "generate a test raw 16 bit audio stream\n"
               "If the file extension is .wav a WAVE header will be added.\n"
               "default: 44100 Hz stereo\n", argv[0]);
        exit(1);
    }

    if (argc > 2) {
        sample_rate = atoi(argv[2]);
        if (sample_rate <= 0) {
            fprintf(stderr, "invalid sample rate: %d\n", sample_rate);
            return 1;
        }
    }

    if (argc > 3) {
        nb_channels = atoi(argv[3]);
        if (nb_channels < 1 || nb_channels > MAX_CHANNELS) {
            fprintf(stderr, "invalid number of channels: %d\n", nb_channels);
            return 1;
        }
    }

    if (argc > 4)
        seed = atoi(argv[4]);

    outfile = fopen(argv[1], "wb");
    if (!outfile) {
        perror(argv[1]);
        return 1;
    }

    if ((ext = strrchr(argv[1], '.')) && !strcmp(ext, ".wav"))
        put_wav_header(sample_rate, nb_channels, 6 * sample_rate);

    /* 1 second of single freq sine at 1000 Hz */
    a = 0;
    for (i = 0; i < 1 * sample_rate; i++) {
        v = (int_cos(a) * 10000) >> FRAC_BITS;
        for (j = 0; j < nb_channels; j++)
            put16(v);
        a += (1000 * FRAC_ONE) / sample_rate;
    }

    /* 1 second of varying frequency between 100 and 10000 Hz */
    a = 0;
    for (i = 0; i < 1 * sample_rate; i++) {
        v = (int_cos(a) * 10000) >> FRAC_BITS;
        for (j = 0; j < nb_channels; j++)
            put16(v);
        f  = 100 + (((10000 - 100) * i) / sample_rate);
        a += (f * FRAC_ONE) / sample_rate;
    }

    /* 0.5 second of low amplitude white noise */
    for (i = 0; i < sample_rate / 2; i++) {
        v = myrnd(&seed, 20000) - 10000;
        for (j = 0; j < nb_channels; j++)
            put16(v);
    }

    /* 0.5 second of high amplitude white noise */
    for (i = 0; i < sample_rate / 2; i++) {
        v = myrnd(&seed, 65535) - 32768;
        for (j = 0; j < nb_channels; j++)
            put16(v);
    }

    /* 1 second of unrelated ramps for each channel */
    for (j = 0; j < nb_channels; j++) {
        taba[j]  = 0;
        tabf1[j] = 100 + myrnd(&seed, 5000);
        tabf2[j] = 100 + myrnd(&seed, 5000);
    }
    for (i = 0; i < 1 * sample_rate; i++) {
        for (j = 0; j < nb_channels; j++) {
            v = (int_cos(taba[j]) * 10000) >> FRAC_BITS;
            put16(v);
            f        = tabf1[j] + (((tabf2[j] - tabf1[j]) * i) / sample_rate);
            taba[j] += (f * FRAC_ONE) / sample_rate;
        }
    }

    /* 2 seconds of 500 Hz with varying volume */
    a    = 0;
    ampa = 0;
    for (i = 0; i < 2 * sample_rate; i++) {
        for (j = 0; j < nb_channels; j++) {
            amp = ((FRAC_ONE + int_cos(ampa)) * 5000) >> FRAC_BITS;
            if (j & 1)
                amp = 10000 - amp;
            v = (int_cos(a) * amp) >> FRAC_BITS;
            put16(v);
            a    += (500 * FRAC_ONE) / sample_rate;
            ampa += (2 * FRAC_ONE) / sample_rate;
        }
    }

    fclose(outfile);
    return 0;
}
