#!/usr/bin/perl
# A perl script to generate real and binary sinusoid data.
# Accurate to 31 bits.
# R. Winters - 2/2/2002

$two_pi=2*3.141592653589732384626433;

$bits=$ARGV[0];
$samples=$ARGV[1];
$cycles=$ARGV[2];
$amplitude=$ARGV[3];
$offset=$ARGV[4];
$phase=$ARGV[5];

if ($bits eq "" || $samples eq "" || $cycles eq "" || $amplitude eq "" || $offset eq "" || $phase eq "") {
    print "Usage: sinegen.pl bits samples cycles amplitude offset phase[deg]\n";
    exit -1;
}

$scale=(2**($bits-1))-0.5;         # real minus 1/2 bit
$theta=$two_pi*$cycles/$samples;   # radians
$phi=($phase/360)*$two_pi;         # radians

print "sample\ttheta\tvolts\tval\tbinary\t2sComp\n";
for ($j=0;$j<$samples;$j++)
{
    $val=$scale*(sin(($theta*$j)+$phi)+1.0);
    $volts=$offset+($amplitude/2)*(sin(($theta*$j)+$phi));
    printf ("%.0f\t%f\t%.20f\t%f\t%s\t%s\n",$j,360*(($theta*$j)+$phi)/$two_pi,$volts,$val,&dec2bin ($val),&dec2bin_2sComp ($val));
}

exit 0;


sub dec2bin 
{
    my $binary="";
    $decimal=sprintf("%.0f",@_[0]); #printf "decimal=$decimal\n";
    for ($i=$bits-1;$i>=0;$i--)
    {
	  $resolv=$decimal/(2**$i);
          if ($resolv>=1.0) {$binary = $binary."1";} else {$binary=$binary."0";}
          $decimal=$decimal%(2**$i);
#         print "i=$i, resolv=$resolv, decimal=$decimal, binary=$binary\n";
    }
    return $binary;
}

sub dec2bin_2sComp
{
    my $twosComp="";
    $decimal=sprintf("%.0f",@_[0]); #printf "decimal=$decimal\n";
    if($decimal >= 2**($bits-1)){$decimal=$decimal-2**($bits-1);}else{$decimal=$decimal+2**($bits-1);}
    for ($i=$bits-1;$i>=0;$i--)
    {
	  $resolv=$decimal/(2**$i);
          if ($resolv>=1.0) {$twosComp = $twosComp."1";} else {$twosComp=$twosComp."0";}
          $decimal=$decimal%(2**$i);
#         print "i=$i, resolv=$resolv, decimal=$decimal, twosComp=$twosComp\n";
    }
    return $twosComp;
}

# end program.
