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

         Voicetronix Voice Processing Board (VPB) Software

         Copyright (C) 1999-2009 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 <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <pthread.h>

#include "vpbreg.h"
#include "vpbapi.h"
#include "verbose.h"
#include "../kbhit.h"

// #include "../threads.h"


void *port_thread(void *pv);

int             threads_active; // the number of active threads.
pthread_mutex_t mutex;          // mutex to protect shared data
int             finito;         // flag to signal the program is finished.
float           gain;           // option software record gain


static int arg_exists(int argc, char *argv[], const char *arg)
{ //{{{
	for(int i = 0; i < argc; ++i)
		if(strcmp(argv[i],arg) == 0) return i;

	return 0;
} //}}}

int main(int argc, char * argv[])
{
	int		*h;
	int		x,j,i;
	VPB_VOX		vox;
	VPBREG		v;
	int		arg;
	verbose(1);
	pthread_mutex_init(&mutex,NULL);
	finito = 0;


	if(arg_exists(argc, argv, "-?") || arg_exists(argc, argv, "--help")){
	printf("usage: %s [options]\n\n",argv[0]); 
	printf("--voxon		Voice energy threshold that triggers recording\n");
	printf("--voxoff	Voice energy threshold that depicts silence\n");
	printf("--runon		Time (in ms) elapsed after last voxoff that triggers recording termination\n");
	}
	
	// count the cards and ports
	int num_cards = vpb_get_num_cards();
	int num_ch = 0;

	int ports_per_card[num_cards];

	for (int i = 0; i < num_cards; ++i)
		num_ch += (ports_per_card[i] = vpb_get_ports_per_card(i));

	printf("Found [%d] channels...\n",num_ch);
	pthread_t	allthread[num_ch];
		
	h = new int[num_ch];
	
	if((arg = arg_exists(argc, argv, "--voxon"))!=0) vox.onlevel = atoi(argv[arg+1]);
	if((arg = arg_exists(argc, argv, "--voxoff"))!=0) vox.offlevel = atoi(argv[arg+1]);
	if((arg = arg_exists(argc, argv, "--runon"))!=0) vox.runon = atoi(argv[arg+1]);
	
	pthread_mutex_init(&mutex, NULL);

	// now init each port and start one thread per port
	x=0;
	for(i=0; i<num_cards; i++) {
		for(j=0;j<ports_per_card[i];j++){
			h[x] = vpb_open(i,j);
			vpb_setvox(h[x],&vox);
			if(int pcode = pthread_create(&allthread[x], NULL, port_thread, (void*)&h[x])){
				printf("Failed: Channel[%2d] pthread_create_failed, retcode = %d\n",x,pcode);
				finito = 1;
				break;
			}
			x++;
		}
	}
	printf("%d ports opened!\n", num_ch);

	// do nothing in main loop until return pressed
	while(!kbhit()){
		vpb_sleep(100);
	}
	finito = 1;

	printf("shutting down....\n");
	while(threads_active) {
		vpb_sleep(100);
		printf("threads active: %d\r", threads_active);
	}

	for(i=0; i<num_ch; i++) {
		vpb_close(h[i]);
	}
	delete h;

	return 0;
}

void *port_thread(void *pv)
{
	int		h = *(int*)pv;
	char    	file_name[VPB_MAX_STR];
	int		ret;
	VPB_EVENT 	e;
	char      	s[VPB_MAX_STR];
	int		state=0;

	pthread_mutex_lock(&mutex);
	threads_active++;
	pthread_mutex_unlock(&mutex);
	sprintf(file_name,"linear%02d.wav",h);
	while(!finito) {

		ret = vpb_get_event_ch_sync(h, &e,6000);
		if (ret == VPB_OK){
			vpb_translate_event(&e, s);
			printf("%s",s);
			if (e.type == VPB_VOXON && state ==0 ){
				vpb_record_file_async(h, file_name, VPB_LINEAR);
				printf(")*( Started Recording ch %d!\n",h);
				state=1;
			} else if ((e.type == VPB_VOXOFF)&&(state ==1)){
				vpb_record_terminate(h);
				printf("(*) Stopped Recording ch %d!\n",h);
				state=0;
			}
		}
	}

	pthread_mutex_lock(&mutex);
	threads_active--;
	pthread_mutex_unlock(&mutex);

	return NULL;
}

