/*
 * Siren Encoder/Decoder library
 *
 *   @author: Youness Alaoui <kakaroto@kakaroto.homelinux.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */



#include "siren7.h"


SirenEncoder
Siren7_NewEncoder (int sample_rate)
{
  SirenEncoder encoder = (SirenEncoder) malloc (sizeof (struct stSirenEncoder));
  encoder->sample_rate = sample_rate;

  encoder->WavHeader.riff.RiffId = ME_TO_LE32 (RIFF_ID);
  encoder->WavHeader.riff.RiffSize = sizeof (SirenWavHeader) - 2 * sizeof (int);
  encoder->WavHeader.riff.RiffSize =
      ME_TO_LE32 (encoder->WavHeader.riff.RiffSize);
  encoder->WavHeader.WaveId = ME_TO_LE32 (WAVE_ID);

  encoder->WavHeader.FmtId = ME_TO_LE32 (FMT__ID);
  encoder->WavHeader.FmtSize = ME_TO_LE32 (sizeof (SirenFmtChunk));

  encoder->WavHeader.fmt.fmt.Format = ME_TO_LE16 (0x028E);
  encoder->WavHeader.fmt.fmt.Channels = ME_TO_LE16 (1);
  encoder->WavHeader.fmt.fmt.SampleRate = ME_TO_LE32 (16000);
  encoder->WavHeader.fmt.fmt.ByteRate = ME_TO_LE32 (2000);
  encoder->WavHeader.fmt.fmt.BlockAlign = ME_TO_LE16 (40);
  encoder->WavHeader.fmt.fmt.BitsPerSample = ME_TO_LE16 (0);
  encoder->WavHeader.fmt.ExtraSize = ME_TO_LE16 (2);
  encoder->WavHeader.fmt.DctLength = ME_TO_LE16 (320);

  encoder->WavHeader.FactId = ME_TO_LE32 (FACT_ID);
  encoder->WavHeader.FactSize = ME_TO_LE32 (sizeof (int));
  encoder->WavHeader.Samples = ME_TO_LE32 (0);

  encoder->WavHeader.DataId = ME_TO_LE32 (DATA_ID);
  encoder->WavHeader.DataSize = ME_TO_LE32 (0);

  memset (encoder->context, 0, sizeof (encoder->context));

  siren_init ();
  return encoder;
}

void
Siren7_CloseEncoder (SirenEncoder encoder)
{
  free (encoder);
}



int
Siren7_EncodeFrame (SirenEncoder encoder, unsigned char *DataIn,
    unsigned char *DataOut)
{
  int number_of_coefs,
      sample_rate_bits,
      rate_control_bits,
      rate_control_possibilities,
      checksum_bits,
      esf_adjustment,
      scale_factor, number_of_regions, sample_rate_code, bits_per_frame;
  int sample_rate = encoder->sample_rate;

  static int absolute_region_power_index[28] = { 0 };
  static int power_categories[28] = { 0 };
  static int category_balance[28] = { 0 };
  static int drp_num_bits[30] = { 0 };
  static int drp_code_bits[30] = { 0 };
  static int region_mlt_bit_counts[28] = { 0 };
  static int region_mlt_bits[112] = { 0 };
  int ChecksumTable[4] = { 0x7F80, 0x7878, 0x6666, 0x5555 };
  int i, j;

  int dwRes = 0;
  short out_word;
  int bits_left;
  int current_word_bits_left;
  int region_bit_count;
  unsigned int current_word;
  unsigned int sum;
  unsigned int checksum;
  int temp1 = 0;
  int temp2 = 0;
  int region;
  int idx = 0;
  int envelope_bits = 0;
  int rate_control;
  int number_of_available_bits;

  float coefs[320];
  float In[320];
  short BufferOut[20];
  float *context = encoder->context;

  for (i = 0; i < 320; i++)
    In[i] = (float) ((short) ME_FROM_LE16 (((short *) DataIn)[i]));

  dwRes = siren_rmlt_encode_samples (In, context, 320, coefs);


  if (dwRes != 0)
    return dwRes;

  dwRes =
      GetSirenCodecInfo (1, sample_rate, &number_of_coefs, &sample_rate_bits,
      &rate_control_bits, &rate_control_possibilities, &checksum_bits,
      &esf_adjustment, &scale_factor, &number_of_regions, &sample_rate_code,
      &bits_per_frame);

  if (dwRes != 0)
    return dwRes;

  envelope_bits =
      compute_region_powers (number_of_regions, coefs, drp_num_bits,
      drp_code_bits, absolute_region_power_index, esf_adjustment);

  number_of_available_bits =
      bits_per_frame - rate_control_bits - envelope_bits - sample_rate_bits -
      checksum_bits;

  categorize_regions (number_of_regions, number_of_available_bits,
      absolute_region_power_index, power_categories, category_balance);

  for (region = 0; region < number_of_regions; region++) {
    absolute_region_power_index[region] += 24;
    region_mlt_bit_counts[region] = 0;
  }

  rate_control =
      quantize_mlt (number_of_regions, rate_control_possibilities,
      number_of_available_bits, coefs, absolute_region_power_index,
      power_categories, category_balance, region_mlt_bit_counts,
      region_mlt_bits);

  idx = 0;
  bits_left = 16 - sample_rate_bits;
  out_word = sample_rate_code << (16 - sample_rate_bits);
  drp_num_bits[number_of_regions] = rate_control_bits;
  drp_code_bits[number_of_regions] = rate_control;
  for (region = 0; region <= number_of_regions; region++) {
    i = drp_num_bits[region] - bits_left;
    if (i < 0) {
      out_word += drp_code_bits[region] << -i;
      bits_left -= drp_num_bits[region];
    } else {
      BufferOut[idx++] = out_word + (drp_code_bits[region] >> i);
      bits_left += 16 - drp_num_bits[region];
      out_word = drp_code_bits[region] << bits_left;
    }
  }

  for (region = 0; region < number_of_regions && (16 * idx) < bits_per_frame;
      region++) {
    current_word_bits_left = region_bit_count = region_mlt_bit_counts[region];
    if (current_word_bits_left > 32)
      current_word_bits_left = 32;

    current_word = region_mlt_bits[region * 4];
    i = 1;
    while (region_bit_count > 0 && (16 * idx) < bits_per_frame) {
      if (current_word_bits_left < bits_left) {
        bits_left -= current_word_bits_left;
        out_word +=
            (current_word >> (32 - current_word_bits_left)) << bits_left;
        current_word_bits_left = 0;
      } else {
        BufferOut[idx++] =
            (short) (out_word + (current_word >> (32 - bits_left)));
        current_word_bits_left -= bits_left;
        current_word <<= bits_left;
        bits_left = 16;
        out_word = 0;
      }
      if (current_word_bits_left == 0) {
        region_bit_count -= 32;
        current_word = region_mlt_bits[(region * 4) + i++];
        current_word_bits_left = region_bit_count;
        if (current_word_bits_left > 32)
          current_word_bits_left = 32;
      }
    }
  }


  while ((16 * idx) < bits_per_frame) {
    BufferOut[idx++] = (short) ((0xFFFF >> (16 - bits_left)) + out_word);
    bits_left = 16;
    out_word = 0;
  }

  if (checksum_bits > 0) {
    BufferOut[idx - 1] &= (-1 << checksum_bits);
    sum = 0;
    idx = 0;
    do {
      sum ^= (BufferOut[idx] & 0xFFFF) << (idx % 15);
    } while ((16 * ++idx) < bits_per_frame);

    sum = (sum >> 15) ^ (sum & 0x7FFF);
    checksum = 0;
    for (i = 0; i < 4; i++) {
      temp1 = ChecksumTable[i] & sum;
      for (j = 8; j > 0; j >>= 1) {
        temp2 = temp1 >> j;
        temp1 ^= temp2;
      }
      checksum <<= 1;
      checksum |= temp1 & 1;
    }
    BufferOut[idx - 1] |= ((1 << checksum_bits) - 1) & checksum;
  }


  for (i = 0; i < 20; i++)
#ifdef __BIG_ENDIAN__
    ((short *) DataOut)[i] = BufferOut[i];
#else
    ((short *) DataOut)[i] =
        ((BufferOut[i] << 8) & 0xFF00) | ((BufferOut[i] >> 8) & 0x00FF);
#endif

  encoder->WavHeader.Samples = ME_FROM_LE32 (encoder->WavHeader.Samples);
  encoder->WavHeader.Samples += 320;
  encoder->WavHeader.Samples = ME_TO_LE32 (encoder->WavHeader.Samples);
  encoder->WavHeader.DataSize = ME_FROM_LE32 (encoder->WavHeader.DataSize);
  encoder->WavHeader.DataSize += 40;
  encoder->WavHeader.DataSize = ME_TO_LE32 (encoder->WavHeader.DataSize);
  encoder->WavHeader.riff.RiffSize =
      ME_FROM_LE32 (encoder->WavHeader.riff.RiffSize);
  encoder->WavHeader.riff.RiffSize += 40;
  encoder->WavHeader.riff.RiffSize =
      ME_TO_LE32 (encoder->WavHeader.riff.RiffSize);


  return 0;
}
