/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

#include <math.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>

#include <alsa/asoundlib.h>

#include "cras_client.h"

#define CAPTURE_MORE_COUNT      50
#define PLAYBACK_COUNT          50
#define PLAYBACK_SILENT_COUNT   50
#define PLAYBACK_TIMEOUT_COUNT 100
#define TTY_OUTPUT_SIZE       1024

static double phase = M_PI / 2;
static unsigned rate = 48000;
static unsigned channels = 2;
static snd_pcm_uframes_t buffer_frames = 480;
static snd_pcm_uframes_t period_size = 240;
static snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;

static struct timeval *cras_play_time = NULL;
static struct timeval *cras_cap_time = NULL;
static int noise_threshold = 0x4000;
static char *tty_output_dev = NULL;
static FILE *tty_output = NULL;
static const char tty_zeros_block[TTY_OUTPUT_SIZE] = {0};

static int loop;
static int cold;
static int capture_count;
static int playback_count;
static snd_pcm_sframes_t playback_delay_frames;
static struct timeval sine_start_tv;

// Mutex and the variables to protect.
static pthread_mutex_t latency_test_mutex;
static pthread_cond_t terminate_test;
static pthread_cond_t sine_start;
static int terminate_playback;
static int terminate_capture;
static int sine_started = 0;

static void generate_sine(const snd_pcm_channel_area_t *areas,
                          snd_pcm_uframes_t offset, int count,
                          double *_phase)
{
    static double max_phase = 2. * M_PI;
    double phase = *_phase;
    double step = max_phase * 1000 / (double)rate;
    unsigned char *samples[channels];
    int steps[channels];
    unsigned int chn;
    int format_bits = snd_pcm_format_width(format);
    unsigned int maxval = (1 << (format_bits - 1)) - 1;
    int bps = format_bits / 8;  /* bytes per sample */
    int phys_bps = snd_pcm_format_physical_width(format) / 8;
    int big_endian = snd_pcm_format_big_endian(format) == 1;
    int to_unsigned = snd_pcm_format_unsigned(format) == 1;
    int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
            format == SND_PCM_FORMAT_FLOAT_BE);

    /* Verify and prepare the contents of areas */
    for (chn = 0; chn < channels; chn++) {
        if ((areas[chn].first % 8) != 0) {
            fprintf(stderr, "areas[%i].first == %i, aborting...\n", chn,
                    areas[chn].first);
            exit(EXIT_FAILURE);
        }
        if ((areas[chn].step % 16) != 0) {
            fprintf(stderr, "areas[%i].step == %i, aborting...\n", chn, areas
                    [chn].step);
            exit(EXIT_FAILURE);
        }
        steps[chn] = areas[chn].step / 8;
        samples[chn] = ((unsigned char *)areas[chn].addr) +
                (areas[chn].first / 8) + offset * steps[chn];
    }

    /* Fill the channel areas */
    while (count-- > 0) {
        union {
            float f;
            int i;
        } fval;
        int res, i;
        if (is_float) {
            fval.f = sin(phase) * maxval;
            res = fval.i;
        } else
            res = sin(phase) * maxval;
        if (to_unsigned)
            res ^= 1U << (format_bits - 1);
        for (chn = 0; chn < channels; chn++) {
            /* Generate data in native endian format */
            if (big_endian) {
                for (i = 0; i < bps; i++)
                    *(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
            } else {
                for (i = 0; i < bps; i++)
                    *(samples[chn] + i) = (res >>  i * 8) & 0xff;
            }
            samples[chn] += steps[chn];
        }
        phase += step;
        if (phase >= max_phase)
            phase -= max_phase;
    }
    *_phase = phase;
}

static void config_pcm(snd_pcm_t *handle,
                       unsigned int rate,
                       unsigned int channels,
                       snd_pcm_format_t format,
                       snd_pcm_uframes_t *buffer_size,
                       snd_pcm_uframes_t *period_size)
{
    int err;
    snd_pcm_hw_params_t *hw_params;

    if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
        fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params_any(handle, hw_params)) < 0) {
        fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params_set_access(handle, hw_params,
            SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
        fprintf(stderr, "cannot set access type (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params_set_format(handle, hw_params,
            format)) < 0) {
        fprintf(stderr, "cannot set sample format (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params_set_rate_near(
            handle, hw_params, &rate, 0)) < 0) {
        fprintf(stderr, "cannot set sample rate (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params_set_channels(handle, hw_params, 2)) < 0) {
        fprintf(stderr, "cannot set channel count (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params_set_buffer_size_near(
            handle, hw_params, buffer_size)) < 0) {
        fprintf(stderr, "cannot set channel count (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params_set_period_size_near(
            handle, hw_params, period_size, 0)) < 0) {
        fprintf(stderr, "cannot set channel count (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    if ((err = snd_pcm_hw_params(handle, hw_params)) < 0) {
        fprintf(stderr, "cannot set parameters (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    snd_pcm_hw_params_free(hw_params);

    if ((err = snd_pcm_prepare(handle)) < 0) {
        fprintf(stderr, "cannot prepare audio interface for use (%s)\n",
                snd_strerror(err));
        exit(1);
    }
}

static int capture_some(snd_pcm_t *pcm, short *buf, unsigned len,
                        snd_pcm_sframes_t *cap_delay_frames)
{
    snd_pcm_sframes_t frames = snd_pcm_avail(pcm);
    int err;

    if (frames > 0) {
        frames = frames > len ? len : frames;

        snd_pcm_delay(pcm, cap_delay_frames);
        if ((err = snd_pcm_readi(pcm, buf, frames)) != frames) {
            fprintf(stderr, "read from audio interface failed (%s)\n",
                    snd_strerror(err));
            exit(1);
        }
    }

    return (int)frames;
}

/* Looks for the first sample in buffer whose absolute value exceeds
 * noise_threshold. Returns the index of found sample in frames, -1
 * if not found. */
static int check_for_noise(short *buf, unsigned len, unsigned channels)
{
    unsigned int i;
    for (i = 0; i < len * channels; i++)
        if (abs(buf[i]) > noise_threshold)
            return i / channels;
    return -1;
}

static unsigned long subtract_timevals(const struct timeval *end,
                                       const struct timeval *beg)
{
    struct timeval diff;
    /* If end is before geb, return 0. */
    if ((end->tv_sec < beg->tv_sec) ||
            ((end->tv_sec == beg->tv_sec) && (end->tv_usec <= beg->tv_usec)))
        diff.tv_sec = diff.tv_usec = 0;
    else {
        if (end->tv_usec < beg->tv_usec) {
            diff.tv_sec = end->tv_sec - beg->tv_sec - 1;
            diff.tv_usec =
                end->tv_usec + 1000000L - beg->tv_usec;
        } else {
            diff.tv_sec = end->tv_sec - beg->tv_sec;
            diff.tv_usec = end->tv_usec - beg->tv_usec;
        }
    }
    return diff.tv_sec * 1000000 + diff.tv_usec;
}

static int cras_capture_tone(struct cras_client *client,
                             cras_stream_id_t stream_id,
                             uint8_t *samples, size_t frames,
                             const struct timespec *sample_time,
                             void *arg)
{
    assert(snd_pcm_format_physical_width(format) == 16);

    short *data = (short *)samples;
    int cap_frames_index;

    if (!sine_started || terminate_capture) {
        return frames;
    }

    if ((cap_frames_index = check_for_noise(data, frames, channels)) >= 0) {
        fprintf(stderr, "Got noise\n");

        struct timespec shifted_time = *sample_time;
        shifted_time.tv_nsec += 1000000000L / rate * cap_frames_index;
        while (shifted_time.tv_nsec > 1000000000L) {
            shifted_time.tv_sec++;
            shifted_time.tv_nsec -= 1000000000L;
        }
        cras_client_calc_capture_latency(&shifted_time, (struct timespec *)arg);
        cras_cap_time = (struct timeval *)malloc(sizeof(*cras_cap_time));
        gettimeofday(cras_cap_time, NULL);

        // Terminate the test since noise got captured.
        pthread_mutex_lock(&latency_test_mutex);
        terminate_capture = 1;
        pthread_cond_signal(&terminate_test);
        pthread_mutex_unlock(&latency_test_mutex);
    }

    return frames;
}

/* Callback for tone playback.  Playback latency will be passed
 * as arg and updated at the first sine tone right after silent.
 */
static int cras_play_tone(struct cras_client *client,
                          cras_stream_id_t stream_id,
                          uint8_t *samples, size_t frames,
                          const struct timespec *sample_time,
                          void *arg)
{
    snd_pcm_channel_area_t *areas;
    int chn;
    size_t sample_bytes;

    sample_bytes = snd_pcm_format_physical_width(format) / 8;

    areas = calloc(channels, sizeof(snd_pcm_channel_area_t));
    for (chn = 0; chn < channels; chn++) {
        areas[chn].addr = samples + chn * sample_bytes;
        areas[chn].first = 0;
        areas[chn].step = channels *
                snd_pcm_format_physical_width(format);
    }

    if (cold)
        goto play_tone;

    /* Write zero first when playback_count < PLAYBACK_SILENT_COUNT
     * or noise got captured. */
    if (playback_count < PLAYBACK_SILENT_COUNT) {
        memset(samples, 0, sample_bytes * frames * channels);
    } else if (playback_count > PLAYBACK_TIMEOUT_COUNT) {
        // Timeout, terminate test.
        pthread_mutex_lock(&latency_test_mutex);
        terminate_capture = 1;
        pthread_cond_signal(&terminate_test);
        pthread_mutex_unlock(&latency_test_mutex);

        /* for loop mode: to avoid underrun */
        memset(samples, 0, sample_bytes * frames * channels);
    } else {
play_tone:
        generate_sine(areas, 0, frames, &phase);

        if (!sine_started) {
            /* Signal that sine tone started playing and update playback time
             * and latency at first played frame. */
            sine_started = 1;
            cras_client_calc_playback_latency(sample_time,
                    (struct timespec *)arg);
            cras_play_time =
                    (struct timeval *)malloc(sizeof(*cras_play_time));
            gettimeofday(cras_play_time, NULL);
            if (tty_output) {
                fwrite(tty_zeros_block, sizeof(char),
                       TTY_OUTPUT_SIZE, tty_output);
                fflush(tty_output);
            }
        }
    }

    playback_count++;
    return frames;
}

static int stream_error(struct cras_client *client,
                        cras_stream_id_t stream_id,
                        int err,
                        void *arg)
{
    fprintf(stderr, "Stream error %d\n", err);
    return 0;
}

/* Adds stream to cras client.  */
static int cras_add_stream(struct cras_client *client,
                           struct cras_stream_params *params,
                           enum CRAS_STREAM_DIRECTION direction,
                           struct timespec *user_data)
{
    struct cras_audio_format *aud_format;
    cras_playback_cb_t aud_cb;
    cras_error_cb_t error_cb;
    size_t cb_threshold = buffer_frames;
    size_t min_cb_level = buffer_frames;
    int rc = 0;
    cras_stream_id_t stream_id = 0;

    aud_format = cras_audio_format_create(format, rate, channels);
    if (aud_format == NULL)
        return -ENOMEM;

    /* Create and start stream */
    aud_cb = (direction == CRAS_STREAM_OUTPUT)
            ? cras_play_tone
            : cras_capture_tone;
    error_cb = stream_error;
    params = cras_client_stream_params_create(direction,
            buffer_frames,
            cb_threshold,
            min_cb_level,
            0,
            0,
            user_data,
            aud_cb,
            error_cb,
            aud_format);
    if (params == NULL)
        return -ENOMEM;

    rc = cras_client_add_stream(client, &stream_id, params);
    if (rc < 0) {
        fprintf(stderr, "Add a stream fail.\n");
        return rc;
    }
    cras_audio_format_destroy(aud_format);
    return 0;
}

static void *alsa_play(void *arg) {
    snd_pcm_t *handle = (snd_pcm_t *)arg;
    short *play_buf;
    snd_pcm_channel_area_t *areas;
    unsigned int chn, num_buffers;
    int err;

    play_buf = calloc(buffer_frames * channels, sizeof(play_buf[0]));
    areas = calloc(channels, sizeof(snd_pcm_channel_area_t));

    for (chn = 0; chn < channels; chn++) {
        areas[chn].addr = play_buf;
        areas[chn].first = chn * snd_pcm_format_physical_width(format);
        areas[chn].step = channels * snd_pcm_format_physical_width(format);
    }

    for (num_buffers = 0; num_buffers < PLAYBACK_SILENT_COUNT; num_buffers++) {
        if ((err = snd_pcm_writei(handle, play_buf, period_size))
                != period_size) {
            fprintf(stderr, "write to audio interface failed (%s)\n",
                    snd_strerror(err));
            exit(1);
        }
    }

    generate_sine(areas, 0, period_size, &phase);
    snd_pcm_delay(handle, &playback_delay_frames);
    gettimeofday(&sine_start_tv, NULL);

    num_buffers = 0;
    int avail_frames;

    /* Play a sine wave and look for it on capture thread.
     * This will fail for latency > 500mS. */
    while (!terminate_playback && num_buffers < PLAYBACK_COUNT) {
        avail_frames = snd_pcm_avail(handle);
        if (avail_frames >= period_size) {
            pthread_mutex_lock(&latency_test_mutex);
            if (!sine_started) {
                sine_started = 1;
                pthread_cond_signal(&sine_start);
            }
            pthread_mutex_unlock(&latency_test_mutex);
            if ((err = snd_pcm_writei(handle, play_buf, period_size))
                    != period_size) {
                fprintf(stderr, "write to audio interface failed (%s)\n",
                        snd_strerror(err));
            }
            num_buffers++;
        }
    }
    terminate_playback = 1;

    if (num_buffers == PLAYBACK_COUNT)
        fprintf(stdout, "Audio not detected.\n");

    free(play_buf);
    free(areas);
    return 0;
}

static void *alsa_capture(void *arg) {
    int err;
    short *cap_buf;
    snd_pcm_t *capture_handle = (snd_pcm_t *)arg;
    snd_pcm_sframes_t cap_delay_frames;
    int num_cap, noise_delay_frames;


    cap_buf = calloc(buffer_frames * channels, sizeof(cap_buf[0]));

    pthread_mutex_lock(&latency_test_mutex);
    while (!sine_started) {
        pthread_cond_wait(&sine_start, &latency_test_mutex);
    }
    pthread_mutex_unlock(&latency_test_mutex);

    /* Begin capture. */
    if ((err = snd_pcm_start(capture_handle)) < 0) {
        fprintf(stderr, "cannot start audio interface for use (%s)\n",
                snd_strerror(err));
        exit(1);
    }

    while (!terminate_capture) {
        num_cap = capture_some(capture_handle, cap_buf,
                               buffer_frames, &cap_delay_frames);

        if (num_cap > 0 && (noise_delay_frames = check_for_noise(cap_buf,
                num_cap, channels)) >= 0) {
            struct timeval cap_time;
            unsigned long latency_us;
            gettimeofday(&cap_time, NULL);

            fprintf(stderr, "Found audio\n");
            fprintf(stderr, "Played at %llu %llu, %ld delay\n",
                    (unsigned long long)sine_start_tv.tv_sec,
                    (unsigned long long)sine_start_tv.tv_usec,
                    playback_delay_frames);
            fprintf(stderr, "Capture at %llu %llu, %ld delay sample %d\n",
                    (unsigned long long)cap_time.tv_sec,
                    (unsigned long long)cap_time.tv_usec,
                    cap_delay_frames, noise_delay_frames);

            latency_us = subtract_timevals(&cap_time, &sine_start_tv);
            fprintf(stdout, "Measured Latency: %lu uS\n", latency_us);

            latency_us = (playback_delay_frames + cap_delay_frames -
                    noise_delay_frames) * 1000000 / rate;
            fprintf(stdout, "Reported Latency: %lu uS\n", latency_us);

            // Noise captured, terminate both threads.
            terminate_playback = 1;
            terminate_capture = 1;
        } else {
            // Capture some more buffers after playback thread has terminated.
            if (terminate_playback && capture_count++ < CAPTURE_MORE_COUNT)
                terminate_capture = 1;
        }
    }

    free(cap_buf);
    return 0;
}

void cras_test_latency()
{
    int rc;
    struct cras_client *client = NULL;
    struct cras_stream_params *playback_params = NULL;
    struct cras_stream_params *capture_params = NULL;

    struct timespec playback_latency;
    struct timespec capture_latency;

    rc = cras_client_create(&client);
    if (rc < 0) {
        fprintf(stderr, "Create client fail.\n");
        exit(1);
    }
    rc = cras_client_connect(client);
    if (rc < 0) {
        fprintf(stderr, "Connect to server fail.\n");
        cras_client_destroy(client);
        exit(1);
    }

    if (tty_output_dev) {
        tty_output = fopen(tty_output_dev, "w");
        if (!tty_output)
            fprintf(stderr, "Failed to open TTY output device: %s",
                    tty_output_dev);
        else
            fprintf(stdout, "Opened %s for UART signal\n",
                    tty_output_dev);
    }

    pthread_mutex_init(&latency_test_mutex, NULL);
    pthread_cond_init(&sine_start, NULL);
    pthread_cond_init(&terminate_test, NULL);

    cras_client_run_thread(client);
    // Sleep 500ms to skip input cold start time.
    fprintf(stderr, "Create capture stream and wait for 500ms.\n");
    rc = cras_add_stream(client,
                         capture_params,
                         CRAS_STREAM_INPUT,
                         &capture_latency);
    if (rc < 0) {
        fprintf(stderr, "Fail to add capture stream.\n");
        exit(1);
    }
    struct timespec delay = { .tv_sec = 0, .tv_nsec = 500000000 };
    nanosleep(&delay, NULL);

    fprintf(stderr, "Create playback stream.\n");
    rc = cras_add_stream(client,
                         playback_params,
                         CRAS_STREAM_OUTPUT,
                         &playback_latency);
    if (rc < 0) {
        fprintf(stderr, "Fail to add playback stream.\n");
        exit(1);
    }

again:
    pthread_mutex_lock(&latency_test_mutex);
    while (!terminate_capture) {
        pthread_cond_wait(&terminate_test, &latency_test_mutex);
    }
    pthread_mutex_unlock(&latency_test_mutex);

    if (cras_cap_time && cras_play_time) {
        unsigned long playback_latency_us, capture_latency_us;
        unsigned long latency = subtract_timevals(cras_cap_time,
                                                  cras_play_time);
        fprintf(stdout, "Measured Latency: %lu uS.\n", latency);

        playback_latency_us = (playback_latency.tv_sec * 1000000) +
            (playback_latency.tv_nsec / 1000);
        capture_latency_us = (capture_latency.tv_sec * 1000000) +
            (capture_latency.tv_nsec / 1000);

        fprintf(stdout,
                "Reported Latency: %lu uS.\n"
                "Reported Output Latency: %lu uS.\n"
                "Reported Input Latency: %lu uS.\n",
                playback_latency_us + capture_latency_us,
                playback_latency_us,
                capture_latency_us);
        fflush(stdout);
    } else {
        fprintf(stdout, "Audio not detected.\n");
    }

    if (--loop > 0) {
        if (cras_play_time)
            free(cras_play_time);
        if (cras_cap_time)
            free(cras_cap_time);
        usleep(50000);
        cras_play_time = cras_cap_time = NULL;
        playback_count = 0;

        pthread_mutex_lock(&latency_test_mutex);
        terminate_capture = 0;
        sine_started = 0;
        pthread_mutex_unlock(&latency_test_mutex);
        goto again;
    }

    /* Destruct things. */
    cras_client_stop(client);
    cras_client_stream_params_destroy(playback_params);
    cras_client_stream_params_destroy(capture_params);
    if (tty_output)
        fclose(tty_output);
    if (cras_play_time)
        free(cras_play_time);
    if (cras_cap_time)
        free(cras_cap_time);
}

void alsa_test_latency(char *play_dev, char *cap_dev)
{
    int err;
    snd_pcm_t *playback_handle;
    snd_pcm_t *capture_handle;

    pthread_t capture_thread;
    pthread_t playback_thread;

    if ((err = snd_pcm_open(&playback_handle, play_dev,
                SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
        fprintf(stderr, "cannot open audio device %s (%s)\n",
                play_dev, snd_strerror(err));
        exit(1);
    }
    config_pcm(playback_handle, rate, channels, format, &buffer_frames,
           &period_size);

    if ((err = snd_pcm_open(&capture_handle, cap_dev,
                SND_PCM_STREAM_CAPTURE, 0)) < 0) {
        fprintf(stderr, "cannot open audio device %s (%s)\n",
                cap_dev, snd_strerror(err));
        exit(1);
    }
    config_pcm(capture_handle, rate, channels, format, &buffer_frames,
            &period_size);

    pthread_mutex_init(&latency_test_mutex, NULL);
    pthread_cond_init(&sine_start, NULL);

    pthread_create(&playback_thread, NULL, alsa_play, playback_handle);
    pthread_create(&capture_thread, NULL, alsa_capture, capture_handle);

    pthread_join(capture_thread, NULL);
    pthread_join(playback_thread, NULL);

    snd_pcm_close(playback_handle);
    snd_pcm_close(capture_handle);
}

int main (int argc, char *argv[])
{
    int cras_only = 0;
    char *play_dev = NULL;
    char *cap_dev = NULL;

    int arg;
    while ((arg = getopt(argc, argv, "b:i:o:n:r:p:ct:l:C")) != -1) {
    switch (arg) {
        case 'b':
            buffer_frames = atoi(optarg);
            break;
        case 'c':
            cras_only = 1;
            break;
        case 'i':
            cap_dev = optarg;
            fprintf(stderr, "Assign cap_dev %s\n", cap_dev);
            break;
        case 'n':
            noise_threshold = atoi(optarg);
            break;
        case 'r':
            rate = atoi(optarg);
            break;
        case 'o':
            play_dev = optarg;
            fprintf(stderr, "Assign play_dev %s\n", play_dev);
            break;
        case 'p':
            period_size = atoi(optarg);
            break;
        case 't':
            tty_output_dev = optarg;
            break;
        case 'l':
            loop = atoi(optarg);
            break;
        case 'C':
            cold = 1;
            break;
        default:
            return 1;
        }
    }

    if (loop && cold) {
        fprintf(stderr, "Cold and loop are exclusive.\n");
        exit(1);
    }

    if (cras_only)
        cras_test_latency();
    else {
      if (play_dev == NULL || cap_dev == NULL) {
          fprintf(stderr, "Input/output devices must be set in Alsa mode.\n");
          exit(1);
      }
      alsa_test_latency(play_dev, cap_dev);
    }
    exit(0);
}
