// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <zircon/assert.h>
#include <math.h>
#include <fbl/algorithm.h>
#include <fbl/limits.h>

#include "sine-source.h"

zx_status_t SineSource::Init(float freq,
                             float amp,
                             float duration_secs,
                             uint32_t frame_rate,
                             uint32_t channels,
                             audio_sample_format_t sample_format) {

    if (!frame_rate)
        return ZX_ERR_INVALID_ARGS;

    if (!channels)
        return ZX_ERR_INVALID_ARGS;

    frame_rate_ = frame_rate;
    channels_ = channels;

    frames_to_produce_ = (duration_secs == 0.0)
                       ? fbl::numeric_limits<uint64_t>::max()
                       : static_cast<uint64_t>(duration_secs * static_cast<float>(frame_rate_));
    sine_scalar_ = (freq * 2.0 * M_PI) / frame_rate_;
    amp_ = fbl::clamp<double>(amp, 0.0, 1.0);

    switch(static_cast<audio_sample_format_t>(sample_format & ~AUDIO_SAMPLE_FORMAT_FLAG_MASK)) {
    case AUDIO_SAMPLE_FORMAT_8BIT:       return InitInternal<AUDIO_SAMPLE_FORMAT_8BIT>();
    case AUDIO_SAMPLE_FORMAT_16BIT:      return InitInternal<AUDIO_SAMPLE_FORMAT_16BIT>();
    case AUDIO_SAMPLE_FORMAT_20BIT_IN32: return InitInternal<AUDIO_SAMPLE_FORMAT_20BIT_IN32>();
    case AUDIO_SAMPLE_FORMAT_24BIT_IN32: return InitInternal<AUDIO_SAMPLE_FORMAT_24BIT_IN32>();
    case AUDIO_SAMPLE_FORMAT_32BIT:      return InitInternal<AUDIO_SAMPLE_FORMAT_32BIT>();
    default:                             return ZX_ERR_INVALID_ARGS;
    }
}

zx_status_t SineSource::GetFormat(Format* out_format) {
    if (out_format == nullptr)
        return ZX_ERR_INVALID_ARGS;

    out_format->frame_rate    = frame_rate_;
    out_format->channels      = static_cast<uint16_t>(channels_);
    out_format->sample_format = sample_format_;

    return ZX_OK;
}

zx_status_t SineSource::GetFrames(void* buffer, uint32_t buf_space, uint32_t* out_packed) {
    ZX_DEBUG_ASSERT(get_frames_thunk_ != nullptr);
    return ((*this).*(get_frames_thunk_))(buffer, buf_space, out_packed);
}

namespace {

template <audio_sample_format_t SAMPLE_FORMAT>
struct SampleTraits;

template <>
struct SampleTraits<AUDIO_SAMPLE_FORMAT_8BIT> {
    using SampleType   = uint8_t;
    using ComputedType = int8_t;
    static SampleType encode(ComputedType v) {
        return static_cast<ComputedType>(static_cast<SampleType>(v) + 0x80);
    }
};

template <>
struct SampleTraits<AUDIO_SAMPLE_FORMAT_16BIT> {
    using SampleType   = int16_t;
    using ComputedType = int16_t;
    static SampleType encode(ComputedType v) { return v; }
};

template <>
struct SampleTraits<AUDIO_SAMPLE_FORMAT_20BIT_IN32> {
    using SampleType   = int32_t;
    using ComputedType = int32_t;
    static SampleType encode(ComputedType v) {
        return static_cast<SampleType>(static_cast<uint32_t>(v) & 0xFFFFF000);
    }
};

template <>
struct SampleTraits<AUDIO_SAMPLE_FORMAT_24BIT_IN32> {
    using SampleType   = int32_t;
    using ComputedType = int32_t;
    static SampleType encode(ComputedType v) {
        return static_cast<SampleType>(static_cast<uint32_t>(v) & 0xFFFFFF00);
    }
};

template <>
struct SampleTraits<AUDIO_SAMPLE_FORMAT_32BIT> {
    using SampleType   = int32_t;
    using ComputedType = int32_t;
    static SampleType encode(ComputedType v) { return v; }
};

} // Anon namespace

template <audio_sample_format_t SAMPLE_FORMAT>
zx_status_t SineSource::InitInternal() {
    using SampleType   = typename SampleTraits<SAMPLE_FORMAT>::SampleType;
    using ComputedType = typename SampleTraits<SAMPLE_FORMAT>::ComputedType;

    sample_format_ = SAMPLE_FORMAT;
    get_frames_thunk_ = &SineSource::GetFramesInternal<SAMPLE_FORMAT>;
    frame_size_ = static_cast<uint32_t>(sizeof(SampleType) * channels_);
    amp_ *= fbl::numeric_limits<ComputedType>::max() - 1;

    return ZX_OK;
}

template <audio_sample_format_t SAMPLE_FORMAT>
zx_status_t SineSource::GetFramesInternal(void* buffer, uint32_t buf_space, uint32_t* out_packed) {
    using Traits       = SampleTraits<SAMPLE_FORMAT>;
    using SampleType   = typename SampleTraits<SAMPLE_FORMAT>::SampleType;
    using ComputedType = typename SampleTraits<SAMPLE_FORMAT>::ComputedType;

    if ((buffer == nullptr) || (out_packed == nullptr))
        return ZX_ERR_INVALID_ARGS;

    if (finished())
        return ZX_ERR_BAD_STATE;

    ZX_DEBUG_ASSERT(frames_produced_ < frames_to_produce_);
    uint64_t todo = fbl::min<uint64_t>(frames_to_produce_ - frames_produced_,
                                        buf_space / frame_size_);
    double pos = sine_scalar_ * static_cast<double>(frames_produced_);
    auto   buf = reinterpret_cast<SampleType*>(buffer);

    for (uint64_t i = 0; i < todo; ++i) {
        auto val = static_cast<ComputedType>(amp_ * sin(pos));

        for (uint32_t j = 0; j < channels_; ++j)
            *(++buf) = Traits::encode(val);

        pos += sine_scalar_;
    }

    *out_packed = static_cast<uint32_t>(todo * frame_size_);
    frames_produced_ += todo;

    return ZX_OK;
}
