// Copyright 2018 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 <string>

#include "garnet/bin/media/audio_core/mixer/test/audio_performance.h"
#include "garnet/bin/media/audio_core/mixer/test/frequency_set.h"
#include "garnet/bin/media/audio_core/mixer/test/mixer_tests_shared.h"

namespace media::audio::test {

// Convenience abbreviation within this source file to shorten names
using Resampler = ::media::audio::Mixer::Resampler;

// For the given resampler, measure elapsed time over a number of mix jobs.
void AudioPerformance::Profile() {
  printf("\n\n Performance Profiling");

  AudioPerformance::ProfileMixers();
  AudioPerformance::ProfileOutputProducers();
}

void AudioPerformance::ProfileMixers() {
  zx_time_t start_time = zx_clock_get(ZX_CLOCK_MONOTONIC);

  DisplayMixerConfigLegend();
  DisplayMixerColumnHeader();

  ProfileSampler(Resampler::SampleAndHold);
  ProfileSampler(Resampler::LinearInterpolation);

  DisplayMixerColumnHeader();
  DisplayMixerConfigLegend();

  printf("   Total time to profile Mixers: %lu ms\n   --------\n\n",
         (zx_clock_get(ZX_CLOCK_MONOTONIC) - start_time) / 1000000);
}

void AudioPerformance::DisplayMixerColumnHeader() {
  printf("Configuration\t\t    Mean\t   First\t    Best\t   Worst\n");
}

void AudioPerformance::DisplayMixerConfigLegend() {
  printf("\n   Elapsed time in microsec for Mix() to produce %u frames\n",
         kFreqTestBufSize);
  printf(
      "\n   For mixer configuration R-fff.IOGAnnnnn, where:\n"
      "\t     R: Resampler type - [P]oint, [L]inear\n"
      "\t   fff: Format - un8, i16, i24, f32,\n"
      "\t     I: Input channels (one-digit number),\n"
      "\t     O: Output channels (one-digit number),\n"
      "\t     G: Gain factor - [M]ute, [U]nity, [S]caled, [R]amping,\n"
      "\t     A: Accumulate - [-] no or [+] yes,\n"
      "\t nnnnn: Sample rate (five-digit number)\n\n");
}

// Profile the samplers in various input and output channel configurations
void AudioPerformance::ProfileSampler(Resampler sampler_type) {
  ProfileSamplerIn(1, sampler_type);
  ProfileSamplerIn(2, sampler_type);
  ProfileSamplerIn(3, sampler_type);
  ProfileSamplerIn(4, sampler_type);
}

// Based on our lack of support for arbitrary channelization, only profile the
// following channel configurations: 1-1, 1-2, 2-1, 2-2, 3-3, 4-4
void AudioPerformance::ProfileSamplerIn(uint32_t num_input_chans,
                                        Resampler sampler_type) {
  if (num_input_chans > 2) {
    ProfileSamplerChans(num_input_chans, num_input_chans, sampler_type);

  } else {
    ProfileSamplerChans(num_input_chans, 1, sampler_type);
    ProfileSamplerChans(num_input_chans, 2, sampler_type);
  }
}

// Profile the samplers in scenarios with, and without, frame rate conversion
void AudioPerformance::ProfileSamplerChans(uint32_t num_input_chans,
                                           uint32_t num_output_chans,
                                           Resampler sampler_type) {
  ProfileSamplerChansRate(num_input_chans, num_output_chans, sampler_type,
                          48000);
  ProfileSamplerChansRate(num_input_chans, num_output_chans, sampler_type,
                          44100);
}

// Profile the samplers with gains of: Mute, Unity, Scaling (non-mute non-unity)
void AudioPerformance::ProfileSamplerChansRate(uint32_t num_input_chans,
                                               uint32_t num_output_chans,
                                               Resampler sampler_type,
                                               uint32_t source_rate) {
  // Mute scenario
  ProfileSamplerChansRateScale(num_input_chans, num_output_chans, sampler_type,
                               source_rate, GainType::Mute);
  // Unity scenario
  ProfileSamplerChansRateScale(num_input_chans, num_output_chans, sampler_type,
                               source_rate, GainType::Unity);
  // Scaling (non-mute, non-unity) scenario
  ProfileSamplerChansRateScale(num_input_chans, num_output_chans, sampler_type,
                               source_rate, GainType::Scaled);
  // Ramping scenario
  ProfileSamplerChansRateScale(num_input_chans, num_output_chans, sampler_type,
                               source_rate, GainType::Ramped);
}

// Profile the samplers when not accumulating and when accumulating
void AudioPerformance::ProfileSamplerChansRateScale(uint32_t num_input_chans,
                                                    uint32_t num_output_chans,
                                                    Resampler sampler_type,
                                                    uint32_t source_rate,
                                                    GainType gain_type) {
  ProfileSamplerChansRateScaleMix(num_input_chans, num_output_chans,
                                  sampler_type, source_rate, gain_type, false);
  ProfileSamplerChansRateScaleMix(num_input_chans, num_output_chans,
                                  sampler_type, source_rate, gain_type, true);
}

// Profile the samplers when mixing data types: uint8, int16, int24-in-32, float
void AudioPerformance::ProfileSamplerChansRateScaleMix(
    uint32_t num_input_chans, uint32_t num_output_chans, Resampler sampler_type,
    uint32_t source_rate, GainType gain_type, bool accumulate) {
  ProfileMixer<uint8_t>(num_input_chans, num_output_chans, sampler_type,
                        source_rate, gain_type, accumulate);
  ProfileMixer<int16_t>(num_input_chans, num_output_chans, sampler_type,
                        source_rate, gain_type, accumulate);
  ProfileMixer<int32_t>(num_input_chans, num_output_chans, sampler_type,
                        source_rate, gain_type, accumulate);
  ProfileMixer<float>(num_input_chans, num_output_chans, sampler_type,
                      source_rate, gain_type, accumulate);
}

template <typename SampleType>
void AudioPerformance::ProfileMixer(uint32_t num_input_chans,
                                    uint32_t num_output_chans,
                                    Resampler sampler_type,
                                    uint32_t source_rate, GainType gain_type,
                                    bool accumulate) {
  fuchsia::media::AudioSampleFormat sample_format;
  double amplitude;
  std::string format;
  if (std::is_same<SampleType, uint8_t>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::UNSIGNED_8;
    amplitude = std::numeric_limits<int8_t>::max();
    format = "un8";
  } else if (std::is_same<SampleType, int16_t>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
    amplitude = std::numeric_limits<int16_t>::max();
    format = "i16";
  } else if (std::is_same<SampleType, int32_t>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::SIGNED_24_IN_32;
    amplitude = std::numeric_limits<int32_t>::max() & ~0x0FF;
    format = "i24";
  } else if (std::is_same<SampleType, float>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::FLOAT;
    amplitude = 1.0;
    format = "f32";
  } else {
    ASSERT_TRUE(false) << "Unknown mix sample format for testing";
    return;
  }

  uint32_t dest_rate = 48000;
  MixerPtr mixer = SelectMixer(sample_format, num_input_chans, source_rate,
                               num_output_chans, dest_rate, sampler_type);

  uint32_t source_buffer_size = kFreqTestBufSize * dest_rate / source_rate;
  uint32_t source_frames = source_buffer_size + 1;

  std::unique_ptr<SampleType[]> source =
      std::make_unique<SampleType[]>(source_frames * num_input_chans);
  std::unique_ptr<float[]> accum =
      std::make_unique<float[]>(kFreqTestBufSize * num_output_chans);
  uint32_t frac_src_frames = source_frames * Mixer::FRAC_ONE;
  int32_t frac_src_offset;
  uint32_t dest_offset, previous_dest_offset;

  OverwriteCosine(source.get(), source_buffer_size * num_input_chans,
                  FrequencySet::kReferenceFreqs[FrequencySet::kRefFreqIdx],
                  amplitude);

  zx_duration_t first, worst, best, total_elapsed = 0;

  Bookkeeping info;
  info.step_size = (source_rate * Mixer::FRAC_ONE) / dest_rate;
  info.denominator = dest_rate;
  info.rate_modulo =
      (source_rate * Mixer::FRAC_ONE) - (info.step_size * dest_rate);

  float gain_db;
  bool source_mute = false;

  char gain_char;
  switch (gain_type) {
    case GainType::Mute:
      // 0dB, Mute
      gain_db = Gain::kUnityGainDb;
      source_mute = true;
      gain_char = 'M';
      break;
    case GainType::Unity:
      // 0dB
      gain_db = Gain::kUnityGainDb;
      gain_char = 'U';
      break;
    case GainType::Scaled:
      // -42dB
      gain_db = -42.0f;
      gain_char = 'S';
      break;
    case GainType::Ramped:
      // -1dB => -159dB
      gain_db = Gain::kUnityGainDb - 1.0f;
      gain_char = 'R';
      break;
  }

  info.gain.SetDestGain(Gain::kUnityGainDb);
  info.gain.SetDestMute(false);

  for (uint32_t i = 0; i < kNumMixerProfilerRuns; ++i) {
    info.gain.SetSourceGain(gain_db);
    info.gain.SetSourceMute(source_mute);

    if (gain_type == GainType::Ramped) {
      // Ramp within the "greater than Mute but less than Unity" range.
      // Ramp duration assumes a mix duration of less than two secs.
      info.gain.SetSourceGainWithRamp(Gain::kMinGainDb + 1.0f, ZX_SEC(2));
    }

    zx_duration_t elapsed;
    zx_time_t start_time = zx_clock_get(ZX_CLOCK_MONOTONIC);

    dest_offset = 0;
    frac_src_offset = 0;
    info.src_pos_modulo = 0;

    while (dest_offset < kFreqTestBufSize) {
      previous_dest_offset = dest_offset;
      mixer->Mix(accum.get(), kFreqTestBufSize, &dest_offset, source.get(),
                 frac_src_frames, &frac_src_offset, accumulate, &info);

      // Mix() might process less than all of accum, so Advance() after each.
      info.gain.Advance(dest_offset - previous_dest_offset,
                        TimelineRate(source_rate, ZX_SEC(1)));
    }

    elapsed = zx_clock_get(ZX_CLOCK_MONOTONIC) - start_time;

    if (i > 0) {
      worst = std::max(worst, elapsed);
      best = std::min(best, elapsed);
    } else {
      first = elapsed;
      worst = elapsed;
      best = elapsed;
    }
    total_elapsed += elapsed;
  }

  auto mean = static_cast<double>(total_elapsed) / kNumMixerProfilerRuns;
  printf("%c-%s.%u%u%c%c%u:",
         (sampler_type == Resampler::SampleAndHold ? 'P' : 'L'), format.c_str(),
         num_input_chans, num_output_chans, gain_char, (accumulate ? '+' : '-'),
         source_rate);

  printf("\t%9.3lf\t%9.3lf\t%9.3lf\t%9.3lf\n", mean / 1000.0, first / 1000.0,
         best / 1000.0, worst / 1000.0);
}

void AudioPerformance::DisplayOutputColumnHeader() {
  printf("Config\t    Mean\t   First\t    Best\t   Worst\n");
}

void AudioPerformance::DisplayOutputConfigLegend() {
  printf("\n   Elapsed time in microsec to ProduceOutput() %u frames\n",
         kFreqTestBufSize);
  printf(
      "\n   For output configuration FFF-Rn, where:\n"
      "\t   FFF: Format of source data - Un8, I16, I24, F32,\n"
      "\t     R: Range of source data - [S]ilence, [O]ut-of-range, [N]ormal,\n"
      "\t     n: Number of output channels (one-digit number)\n\n");
}

void AudioPerformance::ProfileOutputProducers() {
  zx_time_t start_time = zx_clock_get(ZX_CLOCK_MONOTONIC);

  DisplayOutputConfigLegend();
  DisplayOutputColumnHeader();

  ProfileOutputChans(1);
  ProfileOutputChans(2);
  ProfileOutputChans(4);
  ProfileOutputChans(6);
  ProfileOutputChans(8);

  DisplayOutputColumnHeader();
  DisplayOutputConfigLegend();

  printf("   Total time to profile OutputProducers: %lu ms\n   --------\n\n",
         (zx_clock_get(ZX_CLOCK_MONOTONIC) - start_time) / 1000000);
}

void AudioPerformance::ProfileOutputChans(uint32_t num_chans) {
  ProfileOutputRange(num_chans, OutputDataRange::Silence);
  ProfileOutputRange(num_chans, OutputDataRange::OutOfRange);
  ProfileOutputRange(num_chans, OutputDataRange::Normal);
}

void AudioPerformance::ProfileOutputRange(uint32_t num_chans,
                                          OutputDataRange data_range) {
  ProfileOutputType<uint8_t>(num_chans, data_range);
  ProfileOutputType<int16_t>(num_chans, data_range);
  ProfileOutputType<int32_t>(num_chans, data_range);
  ProfileOutputType<float>(num_chans, data_range);
}

template <typename SampleType>
void AudioPerformance::ProfileOutputType(uint32_t num_chans,
                                         OutputDataRange data_range) {
  fuchsia::media::AudioSampleFormat sample_format;
  std::string format;
  char range;

  if (std::is_same<SampleType, uint8_t>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::UNSIGNED_8;
    format = "Un8";
  } else if (std::is_same<SampleType, int16_t>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::SIGNED_16;
    format = "I16";
  } else if (std::is_same<SampleType, int32_t>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::SIGNED_24_IN_32;
    format = "I24";
  } else if (std::is_same<SampleType, float>::value) {
    sample_format = fuchsia::media::AudioSampleFormat::FLOAT;
    format = "F32";
  } else {
    ASSERT_TRUE(false) << "Unknown output sample format for testing";
    return;
  }

  audio::OutputProducerPtr output_producer =
      SelectOutputProducer(sample_format, num_chans);

  uint32_t num_samples = kFreqTestBufSize * num_chans;

  std::unique_ptr<float[]> accum = std::make_unique<float[]>(num_samples);
  std::unique_ptr<SampleType[]> dest =
      std::make_unique<SampleType[]>(num_samples);

  switch (data_range) {
    case OutputDataRange::Silence:
      range = 'S';
      break;
    case OutputDataRange::OutOfRange:
      range = 'O';
      for (size_t idx = 0; idx < num_samples; ++idx) {
        accum[idx] = (idx % 2 ? -1.5f : 1.5f);
      }
      break;
    case OutputDataRange::Normal:
      range = 'N';
      OverwriteCosine(accum.get(), num_samples,
                      FrequencySet::kReferenceFreqs[FrequencySet::kRefFreqIdx]);
      break;
    default:
      ASSERT_TRUE(false) << "Unknown output sample format for testing";
      return;
  }

  zx_duration_t first, worst, best, total_elapsed = 0;

  if (data_range == OutputDataRange::Silence) {
    for (uint32_t i = 0; i < kNumOutputProfilerRuns; ++i) {
      zx_duration_t elapsed;
      zx_time_t start_time = zx_clock_get(ZX_CLOCK_MONOTONIC);

      output_producer->FillWithSilence(dest.get(), kFreqTestBufSize);
      elapsed = zx_clock_get(ZX_CLOCK_MONOTONIC) - start_time;

      if (i > 0) {
        worst = std::max(worst, elapsed);
        best = std::min(best, elapsed);
      } else {
        first = elapsed;
        worst = elapsed;
        best = elapsed;
      }
      total_elapsed += elapsed;
    }
  } else {
    for (uint32_t i = 0; i < kNumOutputProfilerRuns; ++i) {
      zx_duration_t elapsed;
      zx_time_t start_time = zx_clock_get(ZX_CLOCK_MONOTONIC);

      output_producer->ProduceOutput(accum.get(), dest.get(), kFreqTestBufSize);
      elapsed = zx_clock_get(ZX_CLOCK_MONOTONIC) - start_time;

      if (i > 0) {
        worst = std::max(worst, elapsed);
        best = std::min(best, elapsed);
      } else {
        first = elapsed;
        worst = elapsed;
        best = elapsed;
      }
      total_elapsed += elapsed;
    }
  }

  auto mean = static_cast<double>(total_elapsed) / kNumOutputProfilerRuns;
  printf("%s-%c%u:\t%9.3lf\t%9.3lf\t%9.3lf\t%9.3lf\n", format.c_str(), range,
         num_chans, mean / 1000.0, first / 1000.0, best / 1000.0,
         worst / 1000.0);
}
}  // namespace media::audio::test
