// Copyright (c) 2019 Giorgos Vougioukas
//
// The license can be found in the LICENSE file.

#include <euterpe_mp3/mp3_input.h>

#define DR_MP3_NO_SIMD
#define DR_MP3_IMPLEMENTATION
#include "third_party/miniaudio/extras/dr_mp3.h"

#include "WDL/pcmfmtcvt.h"

RSE_Mp3Input::RSE_Mp3Input()
  : m_current_position(0.0)
  , m_length(0.0)
  , m_channels(2)
  , m_bits_per_sample(16)
  , m_sample_rate(44100)
{}

RSE_Mp3Input::~RSE_Mp3Input()
{
  drmp3_uninit(&m_mp3);
}

bool RSE_Mp3Input::Open(const char *filename)
{
  WDL_ASSERT(filename);

  m_filename.Set(filename);

  if (!drmp3_init_file(&m_mp3, m_filename.Get(), NULL))
  {
    return false;
  }

  m_length = (double)drmp3_get_pcm_frame_count(&m_mp3) / m_mp3.sampleRate;
  m_channels = m_mp3.channels;
  m_bits_per_sample = 16;
  m_sample_rate = m_mp3.sampleRate;

  return true;
}

const char *RSE_Mp3Input::GetType()
{
  return "MP3";
}

const char *RSE_Mp3Input::GetFileName()
{
  return m_filename.Get();
}

int RSE_Mp3Input::GetChannels()
{
  return m_channels;
}

double RSE_Mp3Input::GetSampleRate()
{
  return m_sample_rate;
}

double RSE_Mp3Input::GetLength()
{
  return m_length;
}

int RSE_Mp3Input::GetBitsPerSample()
{
  return 16;
}

double RSE_Mp3Input::GetPosition()
{
  return m_current_position;
}

void RSE_Mp3Input::Seek(double time)
{
  drmp3_uint64 frame = (drmp3_uint64)(time * GetSampleRate());
  if (drmp3_seek_to_pcm_frame(&m_mp3, frame))
  {
    m_current_position = time;
  }
}

int RSE_Mp3Input::GetSamples(SAM *buffer, int length)
{
  m_tmp.Resize(length);
  int copied = (int)drmp3_read_pcm_frames_f32(
    &m_mp3, m_tmp.GetSize() / GetChannels(), m_tmp.Get());

  float *n = m_tmp.Get();

  for (int i = 0; i < copied * GetChannels(); i++)
  {
    buffer[i] = (SAM)n[i];
  }

  m_current_position += copied / GetSampleRate();

  return copied * GetChannels();
}

bool RSE_Mp3Input::IsStreaming()
{
  return false;
}

int RSE_Mp3Input::Extended(int call, void *parm1, void *parm2, void *parm3)
{
  return -1;
}
