// 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 <audio-utils/audio-input.h>
#include <fbl/algorithm.h>
#include <fbl/unique_ptr.h>
#include <fuchsia/media/cpp/fidl.h>
#include <inttypes.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/fit/defer.h>
#include <lib/fit/function.h>
#include <lib/fzl/vmo-mapper.h>
#include <lib/zx/time.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <limits>
#include <stdio.h>
#include <utility>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include "lib/component/cpp/connect.h"
#include "lib/component/cpp/startup_context.h"
#include "lib/fsl/tasks/fd_waiter.h"
#include "lib/media/timeline/timeline_function.h"

#include "garnet/lib/media/wav_writer/wav_writer.h"

constexpr bool kWavWriterEnabled = false;

using media::TimelineFunction;

constexpr uint32_t NUM_CHANNELS = 2u;
constexpr uint32_t INPUT_FRAMES_PER_SEC = 48000u;
constexpr uint32_t INPUT_BUFFER_LENGTH_MSEC = 10u;
constexpr uint32_t INPUT_BUFFER_MIN_FRAMES =
    (INPUT_FRAMES_PER_SEC * INPUT_BUFFER_LENGTH_MSEC) / 1000u;
constexpr zx_time_t PROCESS_CHUNK_TIME = ZX_MSEC(1);
constexpr uint32_t OUTPUT_BUF_MSEC = 1000;
constexpr zx_time_t OUTPUT_BUF_TIME = ZX_MSEC(OUTPUT_BUF_MSEC);
constexpr zx_time_t OUTPUT_SEND_PACKET_OVERHEAD_NSEC = ZX_MSEC(1);

constexpr int32_t MIN_REVERB_DEPTH_MSEC = 1;
constexpr int32_t MAX_REVERB_DEPTH_MSEC = OUTPUT_BUF_MSEC - 10;
constexpr int32_t SMALL_REVERB_DEPTH_STEP = 1;
constexpr int32_t LARGE_REVERB_DEPTH_STEP = 10;
constexpr float MIN_REVERB_FEEDBACK_GAIN = -60.0f;
constexpr float MAX_REVERB_FEEDBACK_GAIN = -3.0f;
constexpr float SMALL_REVERB_GAIN_STEP = 0.5;
constexpr float LARGE_REVERB_GAIN_STEP = 2.5;

constexpr float MIN_FUZZ_GAIN = 1.0;
constexpr float MAX_FUZZ_GAIN = 50.0;
constexpr float SMALL_FUZZ_GAIN_STEP = 0.1;
constexpr float LARGE_FUZZ_GAIN_STEP = 1.0;
constexpr float MIN_FUZZ_MIX = 0.0;
constexpr float MAX_FUZZ_MIX = 1.0;
constexpr float SMALL_FUZZ_MIX_STEP = 0.01;
constexpr float LARGE_FUZZ_MIX_STEP = 0.1;

constexpr float MIN_PREAMP_GAIN = -30.0f;
constexpr float MAX_PREAMP_GAIN = 20.0f;
constexpr float SMALL_PREAMP_GAIN_STEP = 0.1f;
constexpr float LARGE_PREAMP_GAIN_STEP = 1.0f;
constexpr uint32_t PREAMP_GAIN_FRAC_BITS = 12;

constexpr int32_t DEFAULT_REVERB_DEPTH_MSEC = 200;
constexpr float DEFAULT_REVERB_FEEDBACK_GAIN = -4.0f;
constexpr float DEFAULT_FUZZ_GAIN = 0.0;
constexpr float DEFAULT_FUZZ_MIX = 1.0;
constexpr float DEFAULT_PREAMP_GAIN = -5.0f;

using audio::utils::AudioInput;

class FxProcessor {
 public:
  FxProcessor(fbl::unique_ptr<AudioInput> input, fit::closure quit_callback)
      : input_(std::move(input)), quit_callback_(std::move(quit_callback)) {
    FXL_DCHECK(quit_callback_);
  }

  void Startup(fuchsia::media::AudioPtr audio);

 private:
  using EffectFn = void (FxProcessor::*)(int16_t* src, int16_t* dst,
                                         uint32_t frames);

  static inline float Norm(int16_t value) {
    return (value < 0)
               ? static_cast<float>(value) / std::numeric_limits<int16_t>::min()
               : static_cast<float>(value) /
                     std::numeric_limits<int16_t>::max();
  }

  static inline float FuzzNorm(float norm_value, float gain) {
    return 1.0f - expf(-norm_value * gain);
  }

  void OnMinLeadTimeChanged(int64_t new_min_lead_time_nsec);
  void RequestKeystrokeMessage();
  void HandleKeystroke(zx_status_t status, uint32_t events);
  void Shutdown(const char* reason = "unknown");
  void ProcessInput();
  void ProduceOutputPackets(fuchsia::media::StreamPacket* out_pkt1,
                            fuchsia::media::StreamPacket* out_pkt2);
  void ApplyEffect(int16_t* src, uint32_t src_offset, uint32_t src_rb_size,
                   int16_t* dst, uint32_t dst_offset, uint32_t dst_rb_size,
                   uint32_t frames, EffectFn effect);

  void CopyInputEffect(int16_t* src, int16_t* dst, uint32_t frames);
  void PreampInputEffect(int16_t* src, int16_t* dst, uint32_t frames);
  void ReverbMixEffect(int16_t* src, int16_t* dst, uint32_t frames);
  void FuzzEffect(int16_t* src, int16_t* dst, uint32_t frames);
  void MixedFuzzEffect(int16_t* src, int16_t* dst, uint32_t frames);

  fsl::FDWaiter::Callback handle_keystroke_thunk_ = [this](zx_status_t status,
                                                           uint32_t event) {
    HandleKeystroke(status, event);
  };

  void UpdateReverb(bool enabled, int32_t depth_delta = 0,
                    float gain_delta = 0.0f);
  void UpdateFuzz(bool enabled, float gain_delta = 0.0f,
                  float mix_delta = 0.0f);
  void UpdatePreampGain(float delta);

  fzl::VmoMapper output_buf_;
  size_t output_buf_sz_ = 0;
  uint32_t output_buf_frames_ = 0;
  uint64_t output_buf_wp_ = 0;
  int64_t input_rp_ = 0;
  bool shutting_down_ = false;

  bool reverb_enabled_ = false;
  int32_t reverb_depth_msec_ = DEFAULT_REVERB_DEPTH_MSEC;
  float reverb_feedback_gain_ = DEFAULT_REVERB_FEEDBACK_GAIN;
  uint32_t reverb_depth_frames_;
  uint16_t reverb_feedback_gain_fixed_;

  bool fuzz_enabled_ = false;
  float fuzz_gain_ = DEFAULT_FUZZ_GAIN;
  float fuzz_mix_ = DEFAULT_FUZZ_MIX;
  float fuzz_mix_inv_;

  float preamp_gain_ = DEFAULT_PREAMP_GAIN;
  uint16_t preamp_gain_fixed_;

  fbl::unique_ptr<AudioInput> input_;
  fit::closure quit_callback_;
  uint32_t input_buffer_frames_ = 0;
  fuchsia::media::AudioRendererPtr audio_renderer_;
  media::TimelineFunction clock_mono_to_input_wr_ptr_;
  fsl::FDWaiter keystroke_waiter_;
  media::audio::WavWriter<kWavWriterEnabled> wav_writer_;

  int64_t lead_time_frames_ = 0;
  bool lead_time_frames_known_ = false;
};

void FxProcessor::Startup(fuchsia::media::AudioPtr audio) {
  auto cleanup = fit::defer([this] { Shutdown("Startup failure"); });

  zx_thread_set_priority(24 /* HIGH_PRIORITY in LK */);

  if (input_->sample_size() != 2) {
    printf("Invalid input sample size %u\n", input_->sample_size());
    return;
  }

  FXL_DCHECK((input_->ring_buffer_bytes() % input_->frame_sz()) == 0);
  input_buffer_frames_ = input_->ring_buffer_bytes() / input_->frame_sz();

  if (!wav_writer_.Initialize(
          "/tmp/fx.wav", fuchsia::media::AudioSampleFormat::SIGNED_16,
          input_->channel_cnt(), input_->frame_rate(), 16)) {
    printf("Unable to initialize WAV file for recording.\n");
    return;
  }

  // Create an AudioRenderer. Setup connection error handlers.
  audio->CreateAudioRenderer(audio_renderer_.NewRequest());

  audio_renderer_.set_error_handler([this](zx_status_t status) {
    Shutdown("fuchsia::media::AudioRenderer connection closed");
  });

  // Set the stream_type.
  fuchsia::media::AudioStreamType stream_type;
  stream_type.sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
  stream_type.channels = input_->channel_cnt();
  stream_type.frames_per_second = input_->frame_rate();
  audio_renderer_->SetPcmStreamType(std::move(stream_type));

  // Create and map a VMO, to mix and subsequently send data to the renderer.
  // Fill it with silence, then send a (read-only) VMO handle to the renderer.
  output_buf_frames_ = static_cast<uint32_t>(
      (OUTPUT_BUF_TIME * input_->frame_rate()) / 1000000000u);
  output_buf_sz_ = static_cast<size_t>(input_->frame_sz()) * output_buf_frames_;

  zx::vmo rend_vmo;
  zx_status_t res = output_buf_.CreateAndMap(
      output_buf_sz_, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, nullptr, &rend_vmo,
      ZX_RIGHT_READ | ZX_RIGHT_MAP | ZX_RIGHT_TRANSFER);

  // We use only a single payload buffer, and hence when creating each packet we
  // can allow its payload_buffer_id to remain the default value of 0.
  audio_renderer_->AddPayloadBuffer(0, std::move(rend_vmo));

  // We work in Audio Frames as our PTS units. Configure this now.
  audio_renderer_->SetPtsUnits(input_->frame_rate(), 1);

  // Start the input ring buffer.
  res = input_->StartRingBuffer();
  if (res != ZX_OK) {
    printf("Failed to start input ring buffer (res %d)\n", res);
    return;
  }

  // Setup the function which will convert from system ticks to the ring
  // buffer write pointer (in audio frames). Note, we offset by the fifo
  // depth so that the write pointer we get back will be the safe write
  // pointer position; IOW - not where the capture currently is, but where the
  // most recent frame which is guaranteed to be written to system memory is.
  int64_t fifo_frames =
      ((input_->fifo_depth() + input_->frame_sz() - 1) / input_->frame_sz());

  media::TimelineRate frames_per_nsec;
  {
    media::TimelineRate frames_per_sec(input_->frame_rate(), 1);
    media::TimelineRate sec_per_nsec(1, ZX_SEC(1));
    frames_per_nsec =
        media::TimelineRate::Product(frames_per_sec, sec_per_nsec);
  }

  clock_mono_to_input_wr_ptr_ = media::TimelineFunction(
      -fifo_frames, input_->start_time(), frames_per_nsec);

  // Request notifications about the minimum clock lead time requirements. We
  // will be able to start to process the input stream once we know what this
  // number is.
  // TODO(johngro): Set the handler here!
  audio_renderer_.events().OnMinLeadTimeChanged = [this](int64_t nsec) {
    OnMinLeadTimeChanged(nsec);
  };
  audio_renderer_->EnableMinLeadTimeEvents(true);

  // Success. Print out the usage message, and force an update of effect
  // parameters (which will also print their status).
  printf(
      "Welcome to FX. Keybindings are as follows.\n"
      "q : Quit the application.\n"
      "\n== Pre-amp Gain\n"
      "] : Increase the pre-amp gain\n"
      "[ : Decrease the pre-amp gain\n"
      "\n== Reverb/Echo Effect ==\n"
      "r : Toggle Reverb\n"
      "i : Increase reverb feedback gain\n"
      "k : Decrease reverb feedback gain\n"
      "l : Increase reverb delay\n"
      "j : Decrease reverb delay\n"
      "\n== Fuzz Effect ==\n"
      "f : Toggle Fuzz\n"
      "w : Increase the fuzz gain\n"
      "s : Decrease the fuzz gain\n"
      "d : Increase the fuzz mix percentage\n"
      "a : Decrease the fuzz mix percentage\n"
      "\nUse <shift> when adjusting parameters in order to use the large "
      "step size for the parameter.\n"
      "\nCurrent settings are...\n");
  UpdatePreampGain(0.0f);
  UpdateFuzz(fuzz_enabled_);
  UpdateReverb(reverb_enabled_);

  // Start to process keystrokes, then cancel the auto-cleanup and get out..
  RequestKeystrokeMessage();
  cleanup.cancel();
}

void FxProcessor::OnMinLeadTimeChanged(int64_t new_min_lead_time_nsec) {
  const auto& cm_to_frames = clock_mono_to_input_wr_ptr_.rate();
  int64_t new_lead_time_frames = cm_to_frames.Scale(new_min_lead_time_nsec);

  if (new_lead_time_frames > lead_time_frames_) {
    // Note: If the system is currently running, this discontinuity is going to
    // put a pop into our presentation. If this is a huge issue, what we would
    // really want to do is...
    //
    // 1) Take manual control of the routing policy.
    // 2) When outputs get added, decide whether or not we want to make any
    //    routing changes ourselves.
    // 3) If we do, and these changes would effect our lead time requirements,
    //    we should smoothly ramp down our current presentation, let that play
    //    out, then stop the output, make the routing changes, then start
    //    everything back up again.
    //
    // Right now, there are no policy APIs which would allow us to acomplish any
    // of this, so this is the best we can do for the time being.
    lead_time_frames_ = new_lead_time_frames;
  }

  // If this is the first time we are learning about our lead time requirements,
  // it is time to process some input data and start the clock.
  if (!lead_time_frames_known_) {
    lead_time_frames_known_ = true;

    // Offset our initial write pointer by a small number of frames (in addition
    // to our lead time) to allow time for our packet messages to read the mixer
    // and get noticed by the mixing output loops.
    output_buf_wp_ = cm_to_frames.Scale(OUTPUT_SEND_PACKET_OVERHEAD_NSEC);

    // Set up our concept of the input read pointer so that it one
    // PROCESS_CHUNK_TIME behind the current write pointer.
    zx_time_t now = zx_clock_get(ZX_CLOCK_MONOTONIC);
    input_rp_ = clock_mono_to_input_wr_ptr_.Apply(now - PROCESS_CHUNK_TIME);

    // Process the input to produce some output, then start the clock. Note:
    // upon start of playback, we choose to explicitly map the reference time
    // 'now' to the media time (PTS) '0' on our presentation timeline. We will
    // control our clock lead time by writing explicit timestamps on packets
    // using the sum of the current output_buf_wp_ and lead_time_frames_.
    ProcessInput();
    audio_renderer_->PlayNoReply(now, 0);
  }
}

void FxProcessor::RequestKeystrokeMessage() {
  keystroke_waiter_.Wait(handle_keystroke_thunk_, STDIN_FILENO, POLLIN);
}

void FxProcessor::HandleKeystroke(zx_status_t status, uint32_t events) {
  if (shutting_down_) {
    return;
  }

  if (status != ZX_OK) {
    printf("Bad status in HandleKeystroke (status %d)\n", status);
    Shutdown("Keystroke read error");
  }

  char c;
  ssize_t res = ::read(STDIN_FILENO, &c, sizeof(c));
  if (res != 1) {
    printf("Error reading keystroke (res %zd, errno %d)\n", res, errno);
    Shutdown("Keystroke read error");
  }

  switch (c) {
    case 'q':
    case 'Q':
      Shutdown("User requested");
      break;

    case 'r':
    case 'R':
      UpdateReverb(!reverb_enabled_);
      break;
    case 'i':
      UpdateReverb(true, 0, SMALL_REVERB_GAIN_STEP);
      break;
    case 'I':
      UpdateReverb(true, 0, LARGE_REVERB_GAIN_STEP);
      break;
    case 'k':
      UpdateReverb(true, 0, -SMALL_REVERB_GAIN_STEP);
      break;
    case 'K':
      UpdateReverb(true, 0, -LARGE_REVERB_GAIN_STEP);
      break;
    case 'l':
      UpdateReverb(true, SMALL_REVERB_DEPTH_STEP, 0.0f);
      break;
    case 'L':
      UpdateReverb(true, LARGE_REVERB_DEPTH_STEP, 0.0f);
      break;
    case 'j':
      UpdateReverb(true, -SMALL_REVERB_DEPTH_STEP, 0.0f);
      break;
    case 'J':
      UpdateReverb(true, -LARGE_REVERB_DEPTH_STEP, 0.0f);
      break;

    case '[':
      UpdatePreampGain(-SMALL_PREAMP_GAIN_STEP);
      break;
    case '{':
      UpdatePreampGain(-LARGE_PREAMP_GAIN_STEP);
      break;
    case ']':
      UpdatePreampGain(SMALL_PREAMP_GAIN_STEP);
      break;
    case '}':
      UpdatePreampGain(LARGE_PREAMP_GAIN_STEP);
      break;

    case 'f':
    case 'F':
      UpdateFuzz(!fuzz_enabled_);
      break;
    case 'd':
      UpdateFuzz(true, 0.0, SMALL_FUZZ_MIX_STEP);
      break;
    case 'D':
      UpdateFuzz(true, 0.0, LARGE_FUZZ_MIX_STEP);
      break;
    case 'a':
      UpdateFuzz(true, 0.0, -SMALL_FUZZ_MIX_STEP);
      break;
    case 'A':
      UpdateFuzz(true, 0.0, -LARGE_FUZZ_MIX_STEP);
      break;
    case 'w':
      UpdateFuzz(true, SMALL_FUZZ_GAIN_STEP);
      break;
    case 'W':
      UpdateFuzz(true, LARGE_FUZZ_GAIN_STEP);
      break;
    case 's':
      UpdateFuzz(true, -SMALL_FUZZ_GAIN_STEP);
      break;
    case 'S':
      UpdateFuzz(true, -LARGE_FUZZ_GAIN_STEP);
      break;

    default:
      break;
  }

  RequestKeystrokeMessage();
}

void FxProcessor::Shutdown(const char* reason) {
  // We're done (for good or bad): flush (save) the headers; close the WAV file.
  wav_writer_.Close();

  printf("Shutting down, reason = \"%s\"\n", reason);
  shutting_down_ = true;
  audio_renderer_.Unbind();
  input_.reset();
  quit_callback_();
}

void FxProcessor::ProcessInput() {
  fuchsia::media::StreamPacket pkt1, pkt2;

  pkt1.payload_size = 0;
  pkt2.payload_size = 0;

  // Produce output packet(s)  If we do not produce any packets, something is
  // very wrong and we are in the process of shutting down, so just get out now.
  ProduceOutputPackets(&pkt1, &pkt2);
  if (!pkt1.payload_size) {
    return;
  }

  // Send the packet(s)
  audio_renderer_->SendPacketNoReply(std::move(pkt1));
  if (pkt2.payload_size) {
    audio_renderer_->SendPacketNoReply(std::move(pkt2));
  }

  // If the input has been closed by the driver, shutdown.
  if (input_->IsRingBufChannelConnected()) {
    Shutdown("Input unplugged");
    return;
  }

  // Save output audio to WAV file (if configured to do so).
  auto output_base = reinterpret_cast<uint8_t*>(output_buf_.start());
  if (pkt1.payload_size) {
    wav_writer_.Write(output_base + pkt1.payload_offset, pkt1.payload_size);
  }

  if (pkt2.payload_size) {
    wav_writer_.Write(output_base + pkt2.payload_offset, pkt2.payload_size);
  }

  // Schedule our next processing callback.
  async::PostDelayedTask(async_get_default_dispatcher(),
                         [this]() { ProcessInput(); },
                         zx::nsec(PROCESS_CHUNK_TIME));
}

void FxProcessor::ProduceOutputPackets(fuchsia::media::StreamPacket* out_pkt1,
                                       fuchsia::media::StreamPacket* out_pkt2) {
  // Figure out how much input data we have to process.
  zx_time_t now = zx_clock_get(ZX_CLOCK_MONOTONIC);
  int64_t input_wp = clock_mono_to_input_wr_ptr_.Apply(now);
  if (input_wp <= input_rp_) {
    printf("input wp <= rp (wp %" PRId64 " rp %" PRId64 " now %" PRIu64 ")\n",
           input_wp, input_rp_, now);
    Shutdown("Failed to produce output packet");
    return;
  }

  int64_t todo64 = input_wp - input_rp_;
  if (todo64 > input_buffer_frames_) {
    printf(
        "Fell behind by more than the input buffer size "
        "(todo %" PRId64 " buflen %u\n",
        todo64, input_buffer_frames_);
    Shutdown("Failed to produce output packet");
    return;
  }

  uint32_t todo = static_cast<uint32_t>(todo64);
  uint32_t input_start =
      static_cast<uint32_t>(input_rp_) % input_buffer_frames_;
  uint32_t output_start = output_buf_wp_ % output_buf_frames_;
  uint32_t output_space = output_buf_frames_ - output_start;

  // Create the actual output packet(s) based on the amt of data we need to
  // send and the current position of the write pointer in the output ring
  // buffer.
  uint32_t pkt1_frames = fbl::min<uint32_t>(output_space, todo);
  out_pkt1->pts = output_buf_wp_ + lead_time_frames_;
  out_pkt1->payload_offset = output_start * input_->frame_sz();
  out_pkt1->payload_size = pkt1_frames * input_->frame_sz();

  // Does this job wrap the ring?  If so, we need to create 2 packets instead
  // of 1.
  if (pkt1_frames < todo) {
    out_pkt2->pts = out_pkt1->pts + pkt1_frames;
    out_pkt2->payload_offset = 0;
    out_pkt2->payload_size = (todo - pkt1_frames) * input_->frame_sz();
  } else {
    out_pkt2->pts = fuchsia::media::NO_TIMESTAMP;
    out_pkt2->payload_offset = 0;
    out_pkt2->payload_size = 0;
  }

  // Now actually apply effects. Start by just copying the input to the output.
  auto input_base = reinterpret_cast<int16_t*>(input_->ring_buffer());
  auto output_base = reinterpret_cast<int16_t*>(output_buf_.start());
  ApplyEffect(input_base, input_start, input_buffer_frames_, output_base,
              output_start, output_buf_frames_, todo,
              (preamp_gain_ == 0.0) ? &FxProcessor::CopyInputEffect
                                    : &FxProcessor::PreampInputEffect);

  // If enabled, add some fuzz
  if (fuzz_enabled_ && (fuzz_mix_ >= 0.01f)) {
    ApplyEffect(output_base, output_start, output_buf_frames_, output_base,
                output_start, output_buf_frames_, todo,
                (fuzz_mix_ <= 0.99f) ? &FxProcessor::MixedFuzzEffect
                                     : &FxProcessor::FuzzEffect);
  }

  // If enabled, add some reverb.
  if (reverb_enabled_ && (reverb_feedback_gain_fixed_ > 0)) {
    uint32_t reverb_start =
        output_start + (output_buf_frames_ - reverb_depth_frames_);
    if (reverb_start >= output_buf_frames_)
      reverb_start -= output_buf_frames_;

    ApplyEffect(output_base, reverb_start, output_buf_frames_, output_base,
                output_start, output_buf_frames_, todo,
                &FxProcessor::ReverbMixEffect);
  }

  // Finally, update our input read pointer and our output write pointer.
  input_rp_ += todo;
  output_buf_wp_ += todo;
}

void FxProcessor::ApplyEffect(int16_t* src, uint32_t src_offset,
                              uint32_t src_rb_size, int16_t* dst,
                              uint32_t dst_offset, uint32_t dst_rb_size,
                              uint32_t frames, EffectFn effect) {
  while (frames) {
    ZX_DEBUG_ASSERT(src_offset < src_rb_size);
    ZX_DEBUG_ASSERT(dst_offset < dst_rb_size);

    uint32_t src_space = src_rb_size - src_offset;
    uint32_t dst_space = dst_rb_size - dst_offset;
    uint32_t todo = fbl::min(fbl::min(frames, src_space), dst_space);

    // TODO(johngro): Either add fbl::invoke to fbl, or use std::invoke
    // here when we switch to C++17. The syntax for invoking a pointer to
    // non-static method on an object is ugly and hard to understand, and
    // people should not be forced to look at it.
    ((*this).*(effect))(src + (src_offset * NUM_CHANNELS),
                        dst + (dst_offset * NUM_CHANNELS), todo);

    src_offset = (src_space > todo) ? (src_offset + todo) : 0;
    dst_offset = (dst_space > todo) ? (dst_offset + todo) : 0;
    frames -= todo;
  }
}

void FxProcessor::CopyInputEffect(int16_t* src, int16_t* dst, uint32_t frames) {
  ::memcpy(dst, src, frames * sizeof(*dst) * NUM_CHANNELS);
}

void FxProcessor::PreampInputEffect(int16_t* src, int16_t* dst,
                                    uint32_t frames) {
  for (uint32_t i = 0; i < frames * NUM_CHANNELS; ++i) {
    int32_t tmp = src[i];
    tmp *= preamp_gain_fixed_;
    tmp >>= PREAMP_GAIN_FRAC_BITS;
    tmp = fbl::clamp<int32_t>(tmp, std::numeric_limits<int16_t>::min(),
                              std::numeric_limits<int16_t>::max());
    dst[i] = static_cast<int16_t>(tmp);
  }
}

void FxProcessor::ReverbMixEffect(int16_t* src, int16_t* dst, uint32_t frames) {
  // TODO(johngro): We should probably process everything into an intermediate
  // 32 bit (or even 64 bit or float) buffer, and clamp after the fact.
  for (uint32_t i = frames * NUM_CHANNELS; i > 0;) {
    --i;

    int32_t tmp = src[i];
    tmp *= reverb_feedback_gain_fixed_;
    tmp >>= 16;
    tmp += dst[i];
    tmp = fbl::clamp<int32_t>(tmp, std::numeric_limits<int16_t>::min(),
                              std::numeric_limits<int16_t>::max());
    dst[i] = static_cast<int16_t>(tmp);
  }
}

void FxProcessor::FuzzEffect(int16_t* src, int16_t* dst, uint32_t frames) {
  for (uint32_t i = 0; i < frames * NUM_CHANNELS; ++i) {
    float norm = FuzzNorm(Norm(src[i]), fuzz_gain_);
    dst[i] =
        (src[i] < 0)
            ? static_cast<int16_t>(std::numeric_limits<int16_t>::min() * norm)
            : static_cast<int16_t>(std::numeric_limits<int16_t>::max() * norm);
  }
}

void FxProcessor::MixedFuzzEffect(int16_t* src, int16_t* dst, uint32_t frames) {
  for (uint32_t i = 0; i < frames * NUM_CHANNELS; ++i) {
    float norm = Norm(src[i]);
    float fnorm = FuzzNorm(norm, fuzz_gain_);
    float mixed = ((fnorm * fuzz_mix_) + (norm * fuzz_mix_inv_));
    dst[i] =
        (src[i] < 0)
            ? static_cast<int16_t>(std::numeric_limits<int16_t>::min() * mixed)
            : static_cast<int16_t>(std::numeric_limits<int16_t>::max() * mixed);
  }
}

void FxProcessor::UpdateReverb(bool enabled, int32_t depth_delta,
                               float gain_delta) {
  reverb_enabled_ = enabled;

  reverb_depth_msec_ =
      fbl::clamp<uint32_t>(reverb_depth_msec_ + depth_delta,
                           MIN_REVERB_DEPTH_MSEC, MAX_REVERB_DEPTH_MSEC);

  reverb_feedback_gain_ =
      fbl::clamp(reverb_feedback_gain_ + gain_delta, MIN_REVERB_FEEDBACK_GAIN,
                 MAX_REVERB_FEEDBACK_GAIN);

  if (enabled) {
    reverb_depth_frames_ = (input_->frame_rate() * reverb_depth_msec_) / 1000u;

    double gain_scale = pow(10.0, reverb_feedback_gain_ / 20.0);
    reverb_feedback_gain_fixed_ = static_cast<uint16_t>(gain_scale * 0x10000);

    printf("%7s: %u mSec %.1f dB\n", "Reverb", reverb_depth_msec_,
           reverb_feedback_gain_);
  } else {
    printf("%7s: Disabled\n", "Reverb");
  }
}

void FxProcessor::UpdateFuzz(bool enabled, float gain_delta, float mix_delta) {
  fuzz_enabled_ = enabled;
  fuzz_gain_ =
      fbl::clamp(fuzz_gain_ + gain_delta, MIN_FUZZ_GAIN, MAX_FUZZ_GAIN);
  fuzz_mix_ = fbl::clamp(fuzz_mix_ + mix_delta, MIN_FUZZ_MIX, MAX_FUZZ_MIX);
  fuzz_mix_inv_ = 1.0f - fuzz_mix_;

  if (enabled) {
    printf("%7s: Gain %.1f Mix %.1f%%\n", "Fuzz", fuzz_gain_,
           fuzz_mix_ * 100.0f);
  } else {
    printf("%7s: Disabled\n", "Fuzz");
  }
}

void FxProcessor::UpdatePreampGain(float delta) {
  preamp_gain_ =
      fbl::clamp(preamp_gain_ + delta, MIN_PREAMP_GAIN, MAX_PREAMP_GAIN);

  double gain_scale = pow(10.0, preamp_gain_ / 20.0);
  preamp_gain_fixed_ =
      static_cast<uint16_t>(gain_scale * (0x1 << PREAMP_GAIN_FRAC_BITS));

  printf("%7s: %.1f dB\n", "PreGain", preamp_gain_);
}

void usage(const char* prog_name) {
  printf("usage: %s [input_dev_num]\n", prog_name);
}

int main(int argc, char** argv) {
  uint32_t input_num = 0;

  if (argc >= 2) {
    if (1 != sscanf(argv[1], "%u", &input_num)) {
      usage(argv[0]);
      return -1;
    }
  }

  zx_status_t res;
  auto input = AudioInput::Create(input_num);

  res = input->Open();
  if (res != ZX_OK) {
    return res;
  }

  // TODO(johngro) : Fetch the supported stream_types from the audio
  // input itself and select from them, do not hardcode this.
  res = input->SetFormat(48000u, NUM_CHANNELS, AUDIO_SAMPLE_FORMAT_16BIT);
  if (res != ZX_OK) {
    return res;
  }

  res = input->GetBuffer(INPUT_BUFFER_MIN_FRAMES, 0u);
  if (res != ZX_OK) {
    return res;
  }

  async::Loop loop(&kAsyncLoopConfigAttachToThread);

  std::unique_ptr<component::StartupContext> startup_context =
      component::StartupContext::CreateFromStartupInfo();

  fuchsia::media::AudioPtr audio =
      startup_context->ConnectToEnvironmentService<fuchsia::media::Audio>();

  FxProcessor fx(std::move(input), [&loop]() {
    async::PostTask(loop.dispatcher(), [&loop]() { loop.Quit(); });
  });
  fx.Startup(std::move(audio));

  loop.Run();
  return 0;
}
