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

  FILE..: MODULATE.CPP
  AUTHOR: Peter Wintulich
  DATE..: 9 MAY 2005

  FM data encoding functions for caller ID functions.
  
         Voicetronix Voice Processing Board (VPB) Software

         Copyright (C) 1999-2007 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., 51 Franklin St, Fifth Floor, Boston,
         MA  02110-1301  USA

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

#include <cmath>
#include "vpbapi.h"
#include "modulate.h"

#define HAMP 6300
#define LAMP 6300


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

	FUNCTION: bit_encode()
	AUTHOR..: Peter Wintulich
	DATE....: Nov 2002

        'Acc' & 'bt' need to be preserved by the cid composer (per
        thread) to maintain the phase relation ship and prevent bit
        width from accumilating any error, therefor causing a farming
        error.
 
        LAMP & HAMP are amplitudes for the sine generator,
        LAMP for mark, HAMP for space

	bit       	Logic of bit to compose
	*samples_count  returns number of samples
	*samples        array of short samples
	*Acc		Accumilation of sine Radians
	*bt		Bit time refrence
	country	        modulation standard

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

void bit_encode(int bit, int *samples_count, short *samples, double *Acc, int *bt,
		const Country *country)
{ //{{{
	const int    samples_bt[3] = {7,6,7}; // Number of sample times per bit
	const double mark_coeff    = country->fsk_mark;
	const double space_coeff   = country->fsk_space;

	for(int i = 0; i < samples_bt[*bt % 3]; ++i)
	{
		if(bit == 1)
		{
			*Acc += mark_coeff;
			samples[i] = (short)(LAMP * sin(*Acc));
		} else {
			*Acc += space_coeff;
			samples[i] = (short)(HAMP * sin(*Acc));
		}
	}
	*samples_count = samples_bt[*bt];
	*bt += 1;	// advance bit time
	*bt %= 3;
} //}}}

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

	FUNCTION: byte_encode() 
	AUTHOR..: Peter Wintulich
	DATE....: Nov 2002
 
	Encode byte from DLPB into wave buffer *BUFF using bit_encode()
 
	dlpb		Datalink Layer Packet Byte to encode
	*scount		Pointer for wave buffer current sample
	*buff		Pointer to head of wave buffer
	*stime		SINE time
	*bt		Bit Time

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

void byte_encode(char dlpb, int *scount, short *buff, double *stime, int *bt,
		 const Country *country)
{ //{{{
	int	sc;		// sample count per bit
	char	byte;		// temp char to shift bits out with

	bit_encode(0, &sc, &buff[*scount], stime, bt, country);	// Start Bit
	*scount += sc;

	byte = dlpb;		// data bits 0-7
	for (int i=0; i < 8 ; ++i)
	{
		bit_encode((byte & 1? 1:0), &sc, &buff[*scount], stime, bt, country);
		*scount += sc;
		byte = byte >> 1;
	}

	bit_encode(1, &sc, &buff[*scount], stime, bt, country);	// Stop Bit
	*scount += sc;
} //}}}

