/*---------------------------------------------------------------------------*\

	FILE....: hostvox.cpp
	TYPE....: C++ Program
	AUTHOR..: Ben Kramer
	DATE....: 23/02/2006

	To test the hostvox functionality

\*--------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*\

         Voicetronix Voice Processing Board (VPB) Software

         Copyright (C) 1999-2001 Voicetronix www.voicetronix.com.au

         This library is free software; you can redistribute it and/or
         modify it under the terms of the GNU Lesser General Public
         License as published by the Free Software Foundation; either
         version 2.1 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
         Lesser General Public License for more details.

         You should have received a copy of the GNU Lesser General Public
         License along with this library; if not, write to the Free Software
         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
	 USA

\*---------------------------------------------------------------------------*/

#include "vpbapi.h"
#include "verbose.h"
#include "hostvox.h"
#include "mess.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

//#define FRAME (8*20) // 20 ms
#define FRAME 8
#define      VOXMAXLIN               32767   // 0 dB maximum

void printframe(char *buf, int n);
void printsframe(short *buf, int n);
long calcpwrc(char *buf, int n, long y);
long calcpwrB(short *buf, int n, long y);
void calcmaxmin(short *buf, int n);
void remove_dc(short *buf, int n);

int main(int argc, char *argv[])
{
	int    tmp=0;
	WFILE *wavp;
	void  *voxp;
	char   buf[FRAME];
	short  sbuf[FRAME];
	int    frame=0;

	unsigned short mess[10];

	memset(buf,0,sizeof(char)*FRAME);
	// On level
	mess[3] = (USHORT)(VOXMAXLIN*pow(10.0, -40/20.0));
	// Off level
	mess[4] = (USHORT)(VOXMAXLIN*pow(10.0, -40.6/20.0));
	// Runon frames
	//mess[5] = (USHORT)(8*2000/FRAME); // 2000 ms
	mess[5] = (USHORT)(8000/FRAME)*5;
	//printf("m5 %d => %d FRAME %d\n",mess[5],(8000/FRAME), FRAME);
//m5 40000 => 40000 FRAME 160



	if(argc<2){
		printf("Usage: %s <wavefile>\n",argv[0]);
		return(-1);
	}

	verbose(1);

	vpb_wave_open_read(&wavp, argv[1]);
	mprintf("Opened %s...\n",argv[1]);
	hostvox_open(&voxp,0);
	hostvox_update_levels(voxp,mess);

	while(vpb_wave_read(wavp, (char*)sbuf, FRAME*2)){
		frame++;
		//printframe(buf, FRAME);
		//calcmaxmin(sbuf, FRAME);
		//remove_dc(sbuf, FRAME);
		//y=calcpwrB(sbuf, FRAME,y);
		//y=calcpwrc(buf, FRAME,y);
		//printsframe(sbuf, FRAME);
		tmp = hostvox_analyse(voxp, sbuf, FRAME);
		if(tmp != 0){
			printf("tmp = %d at %d ms\n",tmp, frame*(FRAME/8));
		}
	}
	printf("\n");
	hostvox_close(voxp);
	vpb_wave_close_read(wavp);
	return 0;
}

void printframe(char *buf, int n)
{
	int i;
	for(i=0; i<n; i++){
		printf("%02d ",buf[i]);
	}
	printf("\n");
}

void printsframe(short *buf, int n)
{
	int i;
	for(i=0; i<n; i++){
		printf("%02d ",buf[i]);
	}
	printf("\n");
}

long calcpwrc(char *buf, int n, long y)
{
        int i;
        short xmax;
        short yshort;
        long acc;
	xmax =0;

	for (i=0;i<n;i++){
		acc = y >> 16;
		y -= acc << 6;
		y += ((long)abs(buf[i])) << 5;

		yshort = y >> 15;
		if (yshort>xmax)
		xmax = yshort;
	}
	printf("XMAX %d :", xmax);
	return y;
}

long calcpwrB(short *buf, int n, long y)
{
        int i;
        short xmax;
        short yshort;
        long acc=0;
	xmax =0;

	for (i=0;i<n;i++){
		acc += ((long)abs(buf[i]));
	}
	
	y= (y+acc)/(n+1);
	yshort = (short)y;
	printf("XAVG %d :", yshort);
	return y;
}

void calcmaxmin(short *buf, int n)
{
	int i;
	short max=0;
	short min = VOXMAXLIN;
	long acc=0;
	short savg=0;
	for(i=0;i<n;i++){
		if(buf[i]>max)
			max = buf[i];
		if(buf[i]<min)
			min = buf[i];
		acc +=buf[i];
	}
	savg = (short)(acc/n); 
	//printf("MAX %d MIN %d SAVG %d :",max, min, savg);
	
	for(i=0;i<n;i++){
		buf[i] = buf[i] - savg;
	}
}

void remove_dc(short *buf, int n)
{
	int i;
	long acc = 0;
	short savg=0;
	for(i=0;i<n;i++){
		acc +=buf[i];
	}
	savg= (short)(acc/n);
	for(i=0;i<n;i++){
		buf[i] = buf[i] - savg;
	}
}
