/* Copyright (c) 2017 Google Inc.
   Written by Andrew Allen */
/*
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "mathops.h"
#include "os_support.h"
#include "opus_private.h"
#include "opus_defines.h"
#include "opus_projection.h"
#include "opus_multistream.h"
#include "stack_alloc.h"
#include "mapping_matrix.h"

struct OpusProjectionEncoder
{
  opus_int32 mixing_matrix_size_in_bytes;
  opus_int32 demixing_matrix_size_in_bytes;
  /* Encoder states go here */
};

#if !defined(DISABLE_FLOAT_API)
static void opus_projection_copy_channel_in_float(
  opus_val16 *dst,
  int dst_stride,
  const void *src,
  int src_stride,
  int src_channel,
  int frame_size,
  void *user_data
)
{
  mapping_matrix_multiply_channel_in_float((const MappingMatrix*)user_data,
    (const float*)src, src_stride, dst, src_channel, dst_stride, frame_size);
}
#endif

static void opus_projection_copy_channel_in_short(
  opus_val16 *dst,
  int dst_stride,
  const void *src,
  int src_stride,
  int src_channel,
  int frame_size,
  void *user_data
)
{
  mapping_matrix_multiply_channel_in_short((const MappingMatrix*)user_data,
    (const opus_int16*)src, src_stride, dst, src_channel, dst_stride, frame_size);
}

static int get_order_plus_one_from_channels(int channels, int *order_plus_one)
{
  int order_plus_one_;
  int acn_channels;
  int nondiegetic_channels;

  /* Allowed numbers of channels:
   * (1 + n)^2 + 2j, for n = 0...14 and j = 0 or 1.
   */
  if (channels < 1 || channels > 227)
    return OPUS_BAD_ARG;

  order_plus_one_ = isqrt32(channels);
  acn_channels = order_plus_one_ * order_plus_one_;
  nondiegetic_channels = channels - acn_channels;
  if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
    return OPUS_BAD_ARG;

  if (order_plus_one)
    *order_plus_one = order_plus_one_;
  return OPUS_OK;
}

static int get_streams_from_channels(int channels, int mapping_family,
                                     int *streams, int *coupled_streams,
                                     int *order_plus_one)
{
  if (mapping_family == 3)
  {
    if (get_order_plus_one_from_channels(channels, order_plus_one) != OPUS_OK)
      return OPUS_BAD_ARG;
    if (streams)
      *streams = (channels + 1) / 2;
    if (coupled_streams)
      *coupled_streams = channels / 2;
    return OPUS_OK;
  }
  return OPUS_BAD_ARG;
}

static MappingMatrix *get_mixing_matrix(OpusProjectionEncoder *st)
{
  /* void* cast avoids clang -Wcast-align warning */
  return (MappingMatrix *)(void*)((char*)st +
    align(sizeof(OpusProjectionEncoder)));
}

static MappingMatrix *get_demixing_matrix(OpusProjectionEncoder *st)
{
  /* void* cast avoids clang -Wcast-align warning */
  return (MappingMatrix *)(void*)((char*)st +
    align(sizeof(OpusProjectionEncoder) +
    st->mixing_matrix_size_in_bytes));
}

static OpusMSEncoder *get_multistream_encoder(OpusProjectionEncoder *st)
{
  /* void* cast avoids clang -Wcast-align warning */
  return (OpusMSEncoder *)(void*)((char*)st +
    align(sizeof(OpusProjectionEncoder) +
    st->mixing_matrix_size_in_bytes +
    st->demixing_matrix_size_in_bytes));
}

opus_int32 opus_projection_ambisonics_encoder_get_size(int channels,
                                                       int mapping_family)
{
  int nb_streams;
  int nb_coupled_streams;
  int order_plus_one;
  int mixing_matrix_rows, mixing_matrix_cols;
  int demixing_matrix_rows, demixing_matrix_cols;
  opus_int32 mixing_matrix_size, demixing_matrix_size;
  opus_int32 encoder_size;
  int ret;

  ret = get_streams_from_channels(channels, mapping_family, &nb_streams,
                                  &nb_coupled_streams, &order_plus_one);
  if (ret != OPUS_OK)
    return 0;

  if (order_plus_one == 2)
  {
    mixing_matrix_rows = mapping_matrix_foa_mixing.rows;
    mixing_matrix_cols = mapping_matrix_foa_mixing.cols;
    demixing_matrix_rows = mapping_matrix_foa_demixing.rows;
    demixing_matrix_cols = mapping_matrix_foa_demixing.cols;
  }
  else if (order_plus_one == 3)
  {
    mixing_matrix_rows = mapping_matrix_soa_mixing.rows;
    mixing_matrix_cols = mapping_matrix_soa_mixing.cols;
    demixing_matrix_rows = mapping_matrix_soa_demixing.rows;
    demixing_matrix_cols = mapping_matrix_soa_demixing.cols;
  }
  else if (order_plus_one == 4)
  {
    mixing_matrix_rows = mapping_matrix_toa_mixing.rows;
    mixing_matrix_cols = mapping_matrix_toa_mixing.cols;
    demixing_matrix_rows = mapping_matrix_toa_demixing.rows;
    demixing_matrix_cols = mapping_matrix_toa_demixing.cols;
  }
  else
    return 0;

  mixing_matrix_size =
    mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols);
  if (!mixing_matrix_size)
    return 0;

  demixing_matrix_size =
    mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols);
  if (!demixing_matrix_size)
    return 0;

  encoder_size =
      opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
  if (!encoder_size)
    return 0;

  return align(sizeof(OpusProjectionEncoder)) +
    mixing_matrix_size + demixing_matrix_size + encoder_size;
}

int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs,
                                            int channels, int mapping_family,
                                            int *streams, int *coupled_streams,
                                            int application)
{
  MappingMatrix *mixing_matrix;
  MappingMatrix *demixing_matrix;
  OpusMSEncoder *ms_encoder;
  int i;
  int ret;
  int order_plus_one;
  unsigned char mapping[255];

  if (streams == NULL || coupled_streams == NULL) {
    return OPUS_BAD_ARG;
  }

  if (get_streams_from_channels(channels, mapping_family, streams,
    coupled_streams, &order_plus_one) != OPUS_OK)
    return OPUS_BAD_ARG;

  if (mapping_family == 3)
  {
    /* Assign mixing matrix based on available pre-computed matrices. */
    mixing_matrix = get_mixing_matrix(st);
    if (order_plus_one == 2)
    {
      mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows,
        mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain,
        mapping_matrix_foa_mixing_data,
        sizeof(mapping_matrix_foa_mixing_data));
    }
    else if (order_plus_one == 3)
    {
      mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows,
        mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain,
        mapping_matrix_soa_mixing_data,
        sizeof(mapping_matrix_soa_mixing_data));
    }
    else if (order_plus_one == 4)
    {
      mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows,
        mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain,
        mapping_matrix_toa_mixing_data,
        sizeof(mapping_matrix_toa_mixing_data));
    }
    else
      return OPUS_BAD_ARG;

    st->mixing_matrix_size_in_bytes = mapping_matrix_get_size(
      mixing_matrix->rows, mixing_matrix->cols);
    if (!st->mixing_matrix_size_in_bytes)
      return OPUS_BAD_ARG;

    /* Assign demixing matrix based on available pre-computed matrices. */
    demixing_matrix = get_demixing_matrix(st);
    if (order_plus_one == 2)
    {
      mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows,
        mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain,
        mapping_matrix_foa_demixing_data,
        sizeof(mapping_matrix_foa_demixing_data));
    }
    else if (order_plus_one == 3)
    {
      mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows,
        mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain,
        mapping_matrix_soa_demixing_data,
        sizeof(mapping_matrix_soa_demixing_data));
    }
    else if (order_plus_one == 4)
    {
      mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows,
        mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain,
        mapping_matrix_toa_demixing_data,
        sizeof(mapping_matrix_toa_demixing_data));
    }
    else
      return OPUS_BAD_ARG;

    st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(
      demixing_matrix->rows, demixing_matrix->cols);
    if (!st->demixing_matrix_size_in_bytes)
      return OPUS_BAD_ARG;
  }
  else
    return OPUS_UNIMPLEMENTED;

  /* Ensure matrices are large enough for desired coding scheme. */
  if (*streams + *coupled_streams > mixing_matrix->rows ||
      channels > mixing_matrix->cols ||
      channels > demixing_matrix->rows ||
      *streams + *coupled_streams > demixing_matrix->cols)
    return OPUS_BAD_ARG;

  /* Set trivial mapping so each input channel pairs with a matrix column. */
  for (i = 0; i < channels; i++)
    mapping[i] = i;

  /* Initialize multistream encoder with provided settings. */
  ms_encoder = get_multistream_encoder(st);
  ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, *streams,
                                      *coupled_streams, mapping, application);
  return ret;
}

OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
    opus_int32 Fs, int channels, int mapping_family, int *streams,
    int *coupled_streams, int application, int *error)
{
  int size;
  int ret;
  OpusProjectionEncoder *st;

  /* Allocate space for the projection encoder. */
  size = opus_projection_ambisonics_encoder_get_size(channels, mapping_family);
  if (!size) {
    if (error)
      *error = OPUS_ALLOC_FAIL;
    return NULL;
  }
  st = (OpusProjectionEncoder *)opus_alloc(size);
  if (!st)
  {
    if (error)
      *error = OPUS_ALLOC_FAIL;
    return NULL;
  }

  /* Initialize projection encoder with provided settings. */
  ret = opus_projection_ambisonics_encoder_init(st, Fs, channels,
     mapping_family, streams, coupled_streams, application);
  if (ret != OPUS_OK)
  {
    opus_free(st);
    st = NULL;
  }
  if (error)
    *error = ret;
  return st;
}

int opus_projection_encode(OpusProjectionEncoder *st, const opus_int16 *pcm,
                           int frame_size, unsigned char *data,
                           opus_int32 max_data_bytes)
{
  return opus_multistream_encode_native(get_multistream_encoder(st),
    opus_projection_copy_channel_in_short, pcm, frame_size, data,
    max_data_bytes, 16, downmix_int, 0, get_mixing_matrix(st));
}

#ifndef DISABLE_FLOAT_API
#ifdef FIXED_POINT
int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
                                 int frame_size, unsigned char *data,
                                 opus_int32 max_data_bytes)
{
  return opus_multistream_encode_native(get_multistream_encoder(st),
    opus_projection_copy_channel_in_float, pcm, frame_size, data,
    max_data_bytes, 16, downmix_float, 1, get_mixing_matrix(st));
}
#else
int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
                                 int frame_size, unsigned char *data,
                                 opus_int32 max_data_bytes)
{
  return opus_multistream_encode_native(get_multistream_encoder(st),
    opus_projection_copy_channel_in_float, pcm, frame_size, data,
    max_data_bytes, 24, downmix_float, 1, get_mixing_matrix(st));
}
#endif
#endif

void opus_projection_encoder_destroy(OpusProjectionEncoder *st)
{
  opus_free(st);
}

int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...)
{
  va_list ap;
  MappingMatrix *demixing_matrix;
  OpusMSEncoder *ms_encoder;
  int ret = OPUS_OK;

  ms_encoder = get_multistream_encoder(st);
  demixing_matrix = get_demixing_matrix(st);

  va_start(ap, request);
  switch(request)
  {
  case OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST:
  {
    opus_int32 *value = va_arg(ap, opus_int32*);
    if (!value)
    {
      goto bad_arg;
    }
    *value =
      ms_encoder->layout.nb_channels * (ms_encoder->layout.nb_streams
      + ms_encoder->layout.nb_coupled_streams) * sizeof(opus_int16);
  }
  break;
  case OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST:
  {
    opus_int32 *value = va_arg(ap, opus_int32*);
    if (!value)
    {
      goto bad_arg;
    }
    *value = demixing_matrix->gain;
  }
  break;
  case OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST:
  {
    int i, j, k, l;
    int nb_input_streams;
    int nb_output_streams;
    unsigned char *external_char;
    opus_int16 *internal_short;
    opus_int32 external_size;
    opus_int32 internal_size;

    /* (I/O is in relation to the decoder's perspective). */
    nb_input_streams = ms_encoder->layout.nb_streams +
      ms_encoder->layout.nb_coupled_streams;
    nb_output_streams = ms_encoder->layout.nb_channels;

    external_char = va_arg(ap, unsigned char *);
    external_size = va_arg(ap, opus_int32);
    if (!external_char)
    {
      goto bad_arg;
    }
    internal_short = mapping_matrix_get_data(demixing_matrix);
    internal_size = nb_input_streams * nb_output_streams * sizeof(opus_int16);
    if (external_size != internal_size)
    {
      goto bad_arg;
    }

    /* Copy demixing matrix subset to output destination. */
    l = 0;
    for (i = 0; i < nb_input_streams; i++) {
      for (j = 0; j < nb_output_streams; j++) {
        k = demixing_matrix->rows * i + j;
        external_char[2*l] = (unsigned char)internal_short[k];
        external_char[2*l+1] = (unsigned char)(internal_short[k] >> 8);
        l++;
      }
    }
  }
  break;
  default:
  {
    ret = opus_multistream_encoder_ctl_va_list(ms_encoder, request, ap);
  }
  break;
  }
  va_end(ap);
  return ret;

bad_arg:
  va_end(ap);
  return OPUS_BAD_ARG;
}

