// 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 <fuchsia/media/cpp/fidl.h>
#include <fuchsia/scheduler/cpp/fidl.h>
#include <inttypes.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.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/media/cpp/timeline_function.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/zx/time.h>
#include <lib/zx/vmar.h>
#include <lib/zx/vmo.h>
#include <math.h>
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <limits>
#include <memory>
#include <utility>

#include <audio-utils/audio-input.h>
#include <fbl/algorithm.h>

#include "src/lib/fsl/tasks/fd_waiter.h"
#include "src/lib/syslog/cpp/logger.h"
#include "src/media/audio/lib/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(std::unique_ptr<AudioInput> input, fit::closure quit_callback)
      : input_(std::move(input)), quit_callback_(std::move(quit_callback)) {
    FX_DCHECK(quit_callback_);
  }

  void Startup(fuchsia::media::AudioPtr audio,
               fuchsia::scheduler::ProfileProviderSyncPtr profile_provider);

 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_;

  std::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,
                          fuchsia::scheduler::ProfileProviderSyncPtr profile_provider) {
  auto cleanup = fit::defer([this] { Shutdown("Startup failure"); });

  zx_status_t profile_status;
  zx::profile profile;
  zx_status_t fidl_status = profile_provider->GetProfile(
      24 /* HIGH_PRIORITY in LK */, "src/media/audio/examples/fx", &profile_status, &profile);

  if (fidl_status != ZX_OK || profile_status != ZX_OK) {
    printf("GetProfile failed (%d || %d)\n", fidl_status, profile_status);
    return;
  }

  zx_status_t set_status = zx_object_set_profile(zx_thread_self(), profile.get(), 0);
  if (set_status != ZX_OK) {
    printf("zx_object_set_profile failed: %d\n", set_status);
    return;
  }

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

  FX_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_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(std::move(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_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) {
  syslog::InitLogger({"fx"});

  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(&kAsyncLoopConfigAttachToCurrentThread);

  std::unique_ptr<sys::ComponentContext> startup_context = sys::ComponentContext::Create();

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

  fuchsia::scheduler::ProfileProviderSyncPtr profile_provider;
  startup_context->svc()->Connect<fuchsia::scheduler::ProfileProvider>(
      profile_provider.NewRequest());

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

  loop.Run();
  return 0;
}
