/* Copyright (C) 2002 Jean-Marc Valin 
   File: speex.c

   Basic Speex functions

   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.
   
   - Neither the name of the Xiph.org Foundation nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.
   
   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 FOUNDATION 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 "modes.h"
#include <math.h>

#ifndef NULL
#define NULL 0
#endif

#define MAX_IN_SAMPLES 640



void *speex_encoder_init(const SpeexMode *mode)
{
   return mode->enc_init(mode);
}

void *speex_decoder_init(const SpeexMode *mode)
{
   return mode->dec_init(mode);
}

void speex_encoder_destroy(void *state)
{
   (*((SpeexMode**)state))->enc_destroy(state);
}

void speex_decoder_destroy(void *state)
{
   (*((SpeexMode**)state))->dec_destroy(state);
}



int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits)
{
   return (*((SpeexMode**)state))->enc(state, in, bits);
}

int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
{
   return (*((SpeexMode**)state))->dec(state, bits, out);
}



#ifdef FIXED_POINT

int speex_encode(void *state, float *in, SpeexBits *bits)
{
   int i;
   spx_int32_t N;
   spx_int16_t short_in[MAX_IN_SAMPLES];
   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
   for (i=0;i<N;i++)
   {
      if (in[i]>32767.f)
         short_in[i] = 32767;
      else if (in[i]<-32768.f)
         short_in[i] = -32768;
      else
         short_in[i] = (spx_int16_t)floor(.5+in[i]);
   }
   return (*((SpeexMode**)state))->enc(state, short_in, bits);
}

int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
{
   SpeexMode *mode;
   mode = *(SpeexMode**)state;
   return (mode)->enc(state, in, bits);
}

int speex_decode(void *state, SpeexBits *bits, float *out)
{
   int i, ret;
   spx_int32_t N;
   spx_int16_t short_out[MAX_IN_SAMPLES];
   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
   ret = (*((SpeexMode**)state))->dec(state, bits, short_out);
   for (i=0;i<N;i++)
      out[i] = short_out[i];
   return ret;
}

int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
{
   SpeexMode *mode = *(SpeexMode**)state;
   return (mode)->dec(state, bits, out);
}

#else

int speex_encode(void *state, float *in, SpeexBits *bits)
{
   return (*((SpeexMode**)state))->enc(state, in, bits);
}

int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
{
   int i;
   spx_int32_t N;
   float float_in[MAX_IN_SAMPLES];
   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
   for (i=0;i<N;i++)
      float_in[i] = in[i];
   return (*((SpeexMode**)state))->enc(state, float_in, bits);
}

int speex_decode(void *state, SpeexBits *bits, float *out)
{
   return (*((SpeexMode**)state))->dec(state, bits, out);
}

int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
{
   int i;
   spx_int32_t N;
   float float_out[MAX_IN_SAMPLES];
   int ret;
   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
   ret = (*((SpeexMode**)state))->dec(state, bits, float_out);
   for (i=0;i<N;i++)
   {
      if (float_out[i]>32767.f)
         out[i] = 32767;
      else if (float_out[i]<-32768.f)
         out[i] = -32768;
      else
         out[i] = (spx_int16_t)floor(.5+float_out[i]);
   }
   return ret;
}
#endif



int speex_encoder_ctl(void *state, int request, void *ptr)
{
   return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
}

int speex_decoder_ctl(void *state, int request, void *ptr)
{
   return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
}



int nb_mode_query(const void *mode, int request, void *ptr)
{
   const SpeexNBMode *m = (const SpeexNBMode*)mode;
   
   switch (request)
   {
   case SPEEX_MODE_FRAME_SIZE:
      *((int*)ptr)=m->frameSize;
      break;
   case SPEEX_SUBMODE_BITS_PER_FRAME:
      if (*((int*)ptr)==0)
         *((int*)ptr) = NB_SUBMODE_BITS+1;
      else if (m->submodes[*((int*)ptr)]==NULL)
         *((int*)ptr) = -1;
      else
         *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
      break;
   default:
      speex_warning_int("Unknown nb_mode_query request: ", request);
      return -1;
   }
   return 0;
}

int wb_mode_query(const void *mode, int request, void *ptr)
{
   const SpeexSBMode *m = (const SpeexSBMode*)mode;

   switch (request)
   {
   case SPEEX_MODE_FRAME_SIZE:
      *((int*)ptr)=2*m->frameSize;
      break;
   case SPEEX_SUBMODE_BITS_PER_FRAME:
      if (*((int*)ptr)==0)
         *((int*)ptr) = SB_SUBMODE_BITS+1;
      else if (m->submodes[*((int*)ptr)]==NULL)
         *((int*)ptr) = -1;
      else
         *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
      break;
   default:
      speex_warning_int("Unknown wb_mode_query request: ", request);
      return -1;
   }
   return 0;
}


int speex_lib_ctl(int request, void *ptr)
{
   switch (request)
   {
      case SPEEX_LIB_GET_MAJOR_VERSION:
         *((int*)ptr) = SPEEX_MAJOR_VERSION;
         break;
      case SPEEX_LIB_GET_MINOR_VERSION:
         *((int*)ptr) = SPEEX_MINOR_VERSION;
         break;
      case SPEEX_LIB_GET_MICRO_VERSION:
         *((int*)ptr) = SPEEX_MICRO_VERSION;
         break;
      case SPEEX_LIB_GET_EXTRA_VERSION:
         *((const char**)ptr) = SPEEX_EXTRA_VERSION;
         break;
      case SPEEX_LIB_GET_VERSION_STRING:
         *((const char**)ptr) = SPEEX_VERSION;
         break;
      /*case SPEEX_LIB_SET_ALLOC_FUNC:
         break;
      case SPEEX_LIB_GET_ALLOC_FUNC:
         break;
      case SPEEX_LIB_SET_FREE_FUNC:
         break;
      case SPEEX_LIB_GET_FREE_FUNC:
         break;*/
      default:
         speex_warning_int("Unknown wb_mode_query request: ", request);
         return -1;
   }
   return 0;
}
