/*
** Copyright 2011, The Android Open-Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "echo_reference"

#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#include <cutils/log.h>
#include <system/audio.h>
#include <audio_utils/resampler.h>
#include <audio_utils/echo_reference.h>

// echo reference state: bit field indicating if read, write or both are active.
enum state {
    ECHOREF_IDLE = 0x00,        // idle
    ECHOREF_READING = 0x01,     // reading is active
    ECHOREF_WRITING = 0x02      // writing is active
};

struct echo_reference {
    struct echo_reference_itfe itfe;
    int status;                     // init status
    uint32_t state;                 // active state: reading, writing or both
    audio_format_t rd_format;       // read sample format
    uint32_t rd_channel_count;      // read number of channels
    uint32_t rd_sampling_rate;      // read sampling rate in Hz
    size_t rd_frame_size;           // read frame size (bytes per sample)
    audio_format_t wr_format;       // write sample format
    uint32_t wr_channel_count;      // write number of channels
    uint32_t wr_sampling_rate;      // write sampling rate in Hz
    size_t wr_frame_size;           // write frame size (bytes per sample)
    void *buffer;                   // main buffer
    size_t buf_size;                // main buffer size in frames
    size_t frames_in;               // number of frames in main buffer
    void *wr_buf;                   // buffer for input conversions
    size_t wr_buf_size;             // size of conversion buffer in frames
    size_t wr_frames_in;            // number of frames in conversion buffer
    size_t wr_curr_frame_size;      // number of frames given to current write() function
    void *wr_src_buf;               // resampler input buf (either wr_buf or buffer used by write())
    struct timespec wr_render_time; // latest render time indicated by write()
                                    // default ALSA gettimeofday() format
    int32_t  playback_delay;        // playback buffer delay indicated by last write()
    int16_t prev_delta_sign;        // sign of previous delay difference:
                                    //  1: positive, -1: negative, 0: unknown
    uint16_t delta_count;           // number of consecutive delay differences with same sign
    pthread_mutex_t lock;                      // mutex protecting read/write concurrency
    pthread_cond_t cond;                       // condition signaled when data is ready to read
    struct resampler_itfe *resampler;          // input resampler
    struct resampler_buffer_provider provider; // resampler buffer provider
};


int echo_reference_get_next_buffer(struct resampler_buffer_provider *buffer_provider,
                                   struct resampler_buffer* buffer)
{
    struct echo_reference *er;

    if (buffer_provider == NULL) {
        return -EINVAL;
    }

    er = (struct echo_reference *)((char *)buffer_provider -
                                      offsetof(struct echo_reference, provider));

    if (er->wr_src_buf == NULL || er->wr_frames_in == 0) {
        buffer->raw = NULL;
        buffer->frame_count = 0;
        return -ENODATA;
    }

    buffer->frame_count = (buffer->frame_count > er->wr_frames_in) ?
            er->wr_frames_in : buffer->frame_count;
    // this is er->rd_channel_count here as we resample after stereo to mono conversion if any
    buffer->i16 = (int16_t *)er->wr_src_buf + (er->wr_curr_frame_size - er->wr_frames_in) *
            er->rd_channel_count;

    return 0;
}

void echo_reference_release_buffer(struct resampler_buffer_provider *buffer_provider,
                                  struct resampler_buffer* buffer)
{
    struct echo_reference *er;

    if (buffer_provider == NULL) {
        return;
    }

    er = (struct echo_reference *)((char *)buffer_provider -
                                      offsetof(struct echo_reference, provider));

    er->wr_frames_in -= buffer->frame_count;
}

static void echo_reference_reset_l(struct echo_reference *er)
{
    ALOGV("echo_reference_reset_l()");
    free(er->buffer);
    er->buffer = NULL;
    er->buf_size = 0;
    er->frames_in = 0;
    free(er->wr_buf);
    er->wr_buf = NULL;
    er->wr_buf_size = 0;
    er->wr_render_time.tv_sec = 0;
    er->wr_render_time.tv_nsec = 0;
    er->delta_count = 0;
    er->prev_delta_sign = 0;
}

/* additional space in resampler buffer allowing for extra samples to be returned
 * by speex resampler when sample rates ratio is not an integer.
 */
#define RESAMPLER_HEADROOM_SAMPLES   10

static int echo_reference_write(struct echo_reference_itfe *echo_reference,
                         struct echo_reference_buffer *buffer)
{
    struct echo_reference *er = (struct echo_reference *)echo_reference;
    int status = 0;

    if (er == NULL) {
        return -EINVAL;
    }

    pthread_mutex_lock(&er->lock);

    if (buffer == NULL) {
        ALOGV("echo_reference_write() stop write");
        er->state &= ~ECHOREF_WRITING;
        echo_reference_reset_l(er);
        goto exit;
    }

    ALOGV("echo_reference_write() START trying to write %d frames", buffer->frame_count);
    ALOGV("echo_reference_write() playbackTimestamp:[%d].[%d], er->playback_delay:[%d]",
            (int)buffer->time_stamp.tv_sec,
            (int)buffer->time_stamp.tv_nsec, er->playback_delay);

    //ALOGV("echo_reference_write() %d frames", buffer->frame_count);
    // discard writes until a valid time stamp is provided.

    if ((buffer->time_stamp.tv_sec == 0) && (buffer->time_stamp.tv_nsec == 0) &&
        (er->wr_render_time.tv_sec == 0) && (er->wr_render_time.tv_nsec == 0)) {
        goto exit;
    }

    if ((er->state & ECHOREF_WRITING) == 0) {
        ALOGV("echo_reference_write() start write");
        if (er->resampler != NULL) {
            er->resampler->reset(er->resampler);
        }
        er->state |= ECHOREF_WRITING;
    }

    if ((er->state & ECHOREF_READING) == 0) {
        goto exit;
    }

    er->wr_render_time.tv_sec  = buffer->time_stamp.tv_sec;
    er->wr_render_time.tv_nsec = buffer->time_stamp.tv_nsec;

    er->playback_delay = buffer->delay_ns;

    // this will be used in the get_next_buffer, to support variable input buffer sizes
    er->wr_curr_frame_size = buffer->frame_count;

    void *srcBuf;
    size_t inFrames;
    // do stereo to mono and down sampling if necessary
    if (er->rd_channel_count != er->wr_channel_count ||
            er->rd_sampling_rate != er->wr_sampling_rate) {
        size_t wrBufSize = buffer->frame_count;

        inFrames = buffer->frame_count;

        if (er->rd_sampling_rate != er->wr_sampling_rate) {
            inFrames = (buffer->frame_count * er->rd_sampling_rate) / er->wr_sampling_rate +
                                                    RESAMPLER_HEADROOM_SAMPLES;
            // wr_buf is not only used as resampler output but also for stereo to mono conversion
            // output so buffer size is driven by both write and read sample rates
            if (inFrames > wrBufSize) {
                wrBufSize = inFrames;
            }
        }

        if (er->wr_buf_size < wrBufSize) {
            ALOGV("echo_reference_write() increasing write buffer size from %d to %d",
                    er->wr_buf_size, wrBufSize);
            er->wr_buf_size = wrBufSize;
            er->wr_buf = realloc(er->wr_buf, er->wr_buf_size * er->rd_frame_size);
        }

        if (er->rd_channel_count != er->wr_channel_count) {
            // must be stereo to mono
            int16_t *src16 = (int16_t *)buffer->raw;
            int16_t *dst16 = (int16_t *)er->wr_buf;
            size_t frames = buffer->frame_count;
            while (frames--) {
                *dst16++ = (int16_t)(((int32_t)*src16 + (int32_t)*(src16 + 1)) >> 1);
                src16 += 2;
            }
        }
        if (er->wr_sampling_rate != er->rd_sampling_rate) {
            if (er->resampler == NULL) {
                int rc;
                ALOGV("echo_reference_write() new ReSampler(%d, %d)",
                      er->wr_sampling_rate, er->rd_sampling_rate);
                er->provider.get_next_buffer = echo_reference_get_next_buffer;
                er->provider.release_buffer = echo_reference_release_buffer;
                rc = create_resampler(er->wr_sampling_rate,
                                 er->rd_sampling_rate,
                                 er->rd_channel_count,
                                 RESAMPLER_QUALITY_DEFAULT,
                                 &er->provider,
                                 &er->resampler);
                if (rc != 0) {
                    er->resampler = NULL;
                    ALOGV("echo_reference_write() failure to create resampler %d", rc);
                    status = -ENODEV;
                    goto exit;
                }
            }
            // er->wr_src_buf and er->wr_frames_in are used by getNexBuffer() called by the
            // resampler to get new frames
            if (er->rd_channel_count != er->wr_channel_count) {
                er->wr_src_buf = er->wr_buf;
            } else {
                er->wr_src_buf = buffer->raw;
            }
            er->wr_frames_in = buffer->frame_count;
            // inFrames is always more than we need here to get frames remaining from previous runs
            // inFrames is updated by resample() with the number of frames produced
            ALOGV("echo_reference_write() ReSampling(%d, %d)",
                  er->wr_sampling_rate, er->rd_sampling_rate);
            er->resampler->resample_from_provider(er->resampler,
                                                     (int16_t *)er->wr_buf, &inFrames);
            ALOGV_IF(er->wr_frames_in != 0,
                    "echo_reference_write() er->wr_frames_in not 0 (%d) after resampler",
                    er->wr_frames_in);
        }
        srcBuf = er->wr_buf;
    } else {
        inFrames = buffer->frame_count;
        srcBuf = buffer->raw;
    }

    if (er->frames_in + inFrames > er->buf_size) {
        ALOGV("echo_reference_write() increasing buffer size from %d to %d",
                er->buf_size, er->frames_in + inFrames);
                er->buf_size = er->frames_in + inFrames;
                er->buffer = realloc(er->buffer, er->buf_size * er->rd_frame_size);
    }
    memcpy((char *)er->buffer + er->frames_in * er->rd_frame_size,
           srcBuf,
           inFrames * er->rd_frame_size);
    er->frames_in += inFrames;

    ALOGV("echo_reference_write() frames written:[%d], frames total:[%d] buffer size:[%d]\n"
          "                       er->wr_render_time:[%d].[%d], er->playback_delay:[%d]",
          inFrames, er->frames_in, er->buf_size,
          (int)er->wr_render_time.tv_sec, (int)er->wr_render_time.tv_nsec, er->playback_delay);

    pthread_cond_signal(&er->cond);
exit:
    pthread_mutex_unlock(&er->lock);
    ALOGV("echo_reference_write() END");
    return status;
}

// delay jump threshold to update ref buffer: 6 samples at 8kHz in nsecs
#define MIN_DELAY_DELTA_NS (375000*2)
// number of consecutive delta with same sign between expected and actual delay before adjusting
// the buffer
#define MIN_DELTA_NUM 4


static int echo_reference_read(struct echo_reference_itfe *echo_reference,
                         struct echo_reference_buffer *buffer)
{
    struct echo_reference *er = (struct echo_reference *)echo_reference;

    if (er == NULL) {
        return -EINVAL;
    }

    pthread_mutex_lock(&er->lock);

    if (buffer == NULL) {
        ALOGV("echo_reference_read() stop read");
        er->state &= ~ECHOREF_READING;
        goto exit;
    }

    ALOGV("echo_reference_read() START, delayCapture:[%d], "
            "er->frames_in:[%d],buffer->frame_count:[%d]",
    buffer->delay_ns, er->frames_in, buffer->frame_count);

    if ((er->state & ECHOREF_READING) == 0) {
        ALOGV("echo_reference_read() start read");
        echo_reference_reset_l(er);
        er->state |= ECHOREF_READING;
    }

    if ((er->state & ECHOREF_WRITING) == 0) {
        memset(buffer->raw, 0, er->rd_frame_size * buffer->frame_count);
        buffer->delay_ns = 0;
        goto exit;
    }

//    ALOGV("echo_reference_read() %d frames", buffer->frame_count);

    // allow some time for new frames to arrive if not enough frames are ready for read
    if (er->frames_in < buffer->frame_count) {
        uint32_t timeoutMs = (uint32_t)((1000 * buffer->frame_count) / er->rd_sampling_rate / 2);
        struct timespec ts;

        ts.tv_sec  = timeoutMs/1000;
        ts.tv_nsec = timeoutMs%1000;
        pthread_cond_timedwait_relative_np(&er->cond, &er->lock, &ts);

        ALOGV_IF((er->frames_in < buffer->frame_count),
                 "echo_reference_read() waited %d ms but still not enough frames"\
                 " er->frames_in: %d, buffer->frame_count = %d",
                 timeoutMs, er->frames_in, buffer->frame_count);
    }

    int64_t timeDiff;
    struct timespec tmp;

    if ((er->wr_render_time.tv_sec == 0 && er->wr_render_time.tv_nsec == 0) ||
        (buffer->time_stamp.tv_sec == 0 && buffer->time_stamp.tv_nsec == 0)) {
        ALOGV("echo_reference_read(): NEW:timestamp is zero---------setting timeDiff = 0, "\
             "not updating delay this time");
        timeDiff = 0;
    } else {
        if (buffer->time_stamp.tv_nsec < er->wr_render_time.tv_nsec) {
            tmp.tv_sec = buffer->time_stamp.tv_sec - er->wr_render_time.tv_sec - 1;
            tmp.tv_nsec = 1000000000 + buffer->time_stamp.tv_nsec - er->wr_render_time.tv_nsec;
        } else {
            tmp.tv_sec = buffer->time_stamp.tv_sec - er->wr_render_time.tv_sec;
            tmp.tv_nsec = buffer->time_stamp.tv_nsec - er->wr_render_time.tv_nsec;
        }
        timeDiff = (((int64_t)tmp.tv_sec * 1000000000 + tmp.tv_nsec));

        int64_t expectedDelayNs =  er->playback_delay + buffer->delay_ns - timeDiff;

        if (er->resampler != NULL) {
            // Resampler already compensates part of the delay
            int32_t rsmp_delay = er->resampler->delay_ns(er->resampler);
            expectedDelayNs -= rsmp_delay;
        }

        ALOGV("echo_reference_read(): expectedDelayNs[%lld] = "
                "er->playback_delay[%d] + delayCapture[%d] - timeDiff[%lld]",
                expectedDelayNs, er->playback_delay, buffer->delay_ns, timeDiff);

        if (expectedDelayNs > 0) {
            int64_t delayNs = ((int64_t)er->frames_in * 1000000000) / er->rd_sampling_rate;

            int64_t  deltaNs = delayNs - expectedDelayNs;

            ALOGV("echo_reference_read(): EchoPathDelayDeviation between reference and DMA [%lld]",
                    deltaNs);
            if (abs(deltaNs) >= MIN_DELAY_DELTA_NS) {
                // smooth the variation and update the reference buffer only
                // if a deviation in the same direction is observed for more than MIN_DELTA_NUM
                // consecutive reads.
                int16_t delay_sign = (deltaNs >= 0) ? 1 : -1;
                if (delay_sign == er->prev_delta_sign) {
                    er->delta_count++;
                } else {
                    er->delta_count = 1;
                }
                er->prev_delta_sign = delay_sign;

                if (er->delta_count > MIN_DELTA_NUM) {
                    size_t previousFrameIn = er->frames_in;
                    er->frames_in = (size_t)((expectedDelayNs * er->rd_sampling_rate)/1000000000);
                    int offset = er->frames_in - previousFrameIn;

                    ALOGV("echo_reference_read(): deltaNs ENOUGH and %s: "
                            "er->frames_in: %d, previousFrameIn = %d",
                         delay_sign ? "positive" : "negative", er->frames_in, previousFrameIn);

                    if (deltaNs < 0) {
                        // Less data available in the reference buffer than expected
                        if (er->frames_in > er->buf_size) {
                            er->buf_size = er->frames_in;
                            er->buffer  = realloc(er->buffer, er->buf_size * er->rd_frame_size);
                            ALOGV("echo_reference_read(): increasing buffer size to %d",
                                  er->buf_size);
                        }

                        if (offset > 0) {
                            memset((char *)er->buffer + previousFrameIn * er->rd_frame_size,
                                   0, offset * er->rd_frame_size);
                            ALOGV("echo_reference_read(): pushing ref buffer by [%d]", offset);
                        }
                    } else {
                        // More data available in the reference buffer than expected
                        offset = -offset;
                        if (offset > 0) {
                            memcpy(er->buffer, (char *)er->buffer + (offset * er->rd_frame_size),
                                   er->frames_in * er->rd_frame_size);
                            ALOGV("echo_reference_read(): shifting ref buffer by [%d]",
                                  er->frames_in);
                        }
                    }
                }
            } else {
                er->delta_count = 0;
                er->prev_delta_sign = 0;
                ALOGV("echo_reference_read(): Constant EchoPathDelay - difference "
                        "between reference and DMA %lld", deltaNs);
            }
        } else {
            ALOGV("echo_reference_read(): NEGATIVE expectedDelayNs[%lld] =  "\
                 "er->playback_delay[%d] + delayCapture[%d] - timeDiff[%lld]",
                 expectedDelayNs, er->playback_delay, buffer->delay_ns, timeDiff);
        }
    }

    if (er->frames_in < buffer->frame_count) {
        if (buffer->frame_count > er->buf_size) {
            er->buf_size = buffer->frame_count;
            er->buffer  = realloc(er->buffer, er->buf_size * er->rd_frame_size);
            ALOGV("echo_reference_read(): increasing buffer size to %d", er->buf_size);
        }
        // filling up the reference buffer with 0s to match the expected delay.
        memset((char *)er->buffer + er->frames_in * er->rd_frame_size,
            0, (buffer->frame_count - er->frames_in) * er->rd_frame_size);
        er->frames_in = buffer->frame_count;
    }

    memcpy(buffer->raw,
           (char *)er->buffer,
           buffer->frame_count * er->rd_frame_size);

    er->frames_in -= buffer->frame_count;
    memcpy(er->buffer,
           (char *)er->buffer + buffer->frame_count * er->rd_frame_size,
           er->frames_in * er->rd_frame_size);

    // As the reference buffer is now time aligned to the microphone signal there is a zero delay
    buffer->delay_ns = 0;

    ALOGV("echo_reference_read() END %d frames, total frames in %d",
          buffer->frame_count, er->frames_in);

    pthread_cond_signal(&er->cond);

exit:
    pthread_mutex_unlock(&er->lock);
    return 0;
}


int create_echo_reference(audio_format_t rdFormat,
                            uint32_t rdChannelCount,
                            uint32_t rdSamplingRate,
                            audio_format_t wrFormat,
                            uint32_t wrChannelCount,
                            uint32_t wrSamplingRate,
                            struct echo_reference_itfe **echo_reference)
{
    struct echo_reference *er;

    ALOGV("create_echo_reference()");

    if (echo_reference == NULL) {
        return -EINVAL;
    }

    *echo_reference = NULL;

    if (rdFormat != AUDIO_FORMAT_PCM_16_BIT ||
            rdFormat != wrFormat) {
        ALOGW("create_echo_reference bad format rd %d, wr %d", rdFormat, wrFormat);
        return -EINVAL;
    }
    if ((rdChannelCount != 1 && rdChannelCount != 2) ||
            wrChannelCount != 2) {
        ALOGW("create_echo_reference bad channel count rd %d, wr %d", rdChannelCount,
                wrChannelCount);
        return -EINVAL;
    }

    er = (struct echo_reference *)calloc(1, sizeof(struct echo_reference));

    er->itfe.read = echo_reference_read;
    er->itfe.write = echo_reference_write;

    er->state = ECHOREF_IDLE;
    er->rd_format = rdFormat;
    er->rd_channel_count = rdChannelCount;
    er->rd_sampling_rate = rdSamplingRate;
    er->wr_format = wrFormat;
    er->wr_channel_count = wrChannelCount;
    er->wr_sampling_rate = wrSamplingRate;
    er->rd_frame_size = audio_bytes_per_sample(rdFormat) * rdChannelCount;
    er->wr_frame_size = audio_bytes_per_sample(wrFormat) * wrChannelCount;
    *echo_reference = &er->itfe;
    return 0;
}

void release_echo_reference(struct echo_reference_itfe *echo_reference) {
    struct echo_reference *er = (struct echo_reference *)echo_reference;

    if (er == NULL) {
        return;
    }

    ALOGV("EchoReference dstor");
    echo_reference_reset_l(er);
    if (er->resampler != NULL) {
        release_resampler(er->resampler);
    }
    free(er);
}

