// 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/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.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 <algorithm>
#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/media/audio/lib/wav/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_ = nullptr;
  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 = std::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 = std::min(std::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 = std::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 = std::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_ = std::clamp<uint32_t>(reverb_depth_msec_ + depth_delta, MIN_REVERB_DEPTH_MSEC,
                                            MAX_REVERB_DEPTH_MSEC);

  reverb_feedback_gain_ = std::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_ = std::clamp(fuzz_gain_ + gain_delta, MIN_FUZZ_GAIN, MAX_FUZZ_GAIN);
  fuzz_mix_ = std::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_ = std::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::SetTags({"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, 0, 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::CreateAndServeOutgoingDirectory();

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