#!/usr/bin/perl
################################################################################
#                                                                              #
# avrmusicox V0.38 zweistimmige Klangerzeugung (Spieluhr) mit ATMEGA8/88       #
# Script zur Erzeugung der Tabellen					       #
# (c)2006 Jörg Wolfram   joerg@jcwolfram.de   		                       #
#                                                                              #
# Dieses Programm ist freie Software. Sie können es unter den Bedingungen      #
# der GNU General Public License, wie von der Free Software Foundation         #
# veröffentlicht, weitergeben und/oder modifizieren, entweder gemäss           #
# Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version.        #
#                                                                              #
# Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es        #
# Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, auch ohne die     #
# implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN          #
# BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License.      #
#                                                                              #
# Sie sollten ein Exemplar der GNU General Public License zusammen mit         #
# diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free       #
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110,    #
# USA.                                                                         #
#                                                                              #
# Jede Nutzung der Software/Informationen nonkonform zur GPL oder ausserhalb   #
# des Geltungsbereiches der GPL ist untersagt!                                 #
#                                                                              #
################################################################################
$takt=8000000;
$pwm=256;
$maxcount=65536;
$fakt=3;

$sprung=exp(log(2)/12);
$samfrq=$takt/$pwm;

#-------------------------------------------------------------------------------
# generate table with increments for DDS
#-------------------------------------------------------------------------------
open ($fh, ">../src/tables/musictables.inc");
    print $fh ";endheader\n";
    print $fh "ztab:";

for($j=0;$j<8;$j++)
{
    print $fh "\n    .db ";
    for($i=0;$i<8;$i++)
    {
	$x=$i+8*$j;
	$freq=110*$sprung**($x+3);
	$delta=$maxcount*$freq/$samfrq;
	$y=int($delta+0.5);
	if (($y%256)<1) {printf $fh "0x00,"} else {printf $fh "%#2.2x,",$y%256};
	if (($y/256)<1) {printf $fh "0x00"} else {printf $fh "%#2.2x",$y/256};
	if ($i<7) {print $fh ","};
    }	
}

#-------------------------------------------------------------------------------
# generate wavetable for waveform 2 (sine)
#-------------------------------------------------------------------------------

$sin1=0.8;
$cos1=0;
$sin2=0;
$cos2=0;
$sin3=0;
$cos3=0.1;
$sin4=0;
$cos4=0;
$sin5=0.05;
$cos5=0;
$sin6=0;
$cos6=0;
$sin7=0;
$cos7=0.05;

print $fh "\n\nwtab1:";
for($j=0;$j<128;$j++)
{
    print $fh "\n    .db ";
     for($i=0;$i<8;$i++)
    {
	$x=$i+8*$j;
	$y=0;
	$y+=$sin1*32767*sin($x*3.1416/512);
	$y+=$cos1*32767*cos($x*3.1416/512);
	$y+=$sin2*32767*sin($x*3.1416/(512/2));
	$y+=$cos2*32767*cos($x*3.1416/(512/2));
	$y+=$sin3*32767*sin($x*3.1416/(512/3));
	$y+=$cos3*32767*cos($x*3.1416/(512/3));
	$y+=$sin4*32767*sin($x*3.1416/(512/4));
	$y+=$cos4*32767*cos($x*3.1416/(512/4));
	$y+=$sin5*32767*sin($x*3.1416/(512/5));
	$y+=$cos5*32767*cos($x*3.1416/(512/5));
	$y+=$sin6*32767*sin($x*3.1416/(512/6));
	$y+=$cos6*32767*cos($x*3.1416/(512/6));
	$y+=$sin7*32767*sin($x*3.1416/(512/7));
	$y+=$cos7*32767*cos($x*3.1416/(512/7));
	if ($y<(-0.5)) {$y=abs($y)+32768};
	if (($y%256)<1) {printf $fh "0x00,"} else {printf $fh "%#2.2x,",$y%256};
	if (($y/256)<1) {printf $fh "0x00"} else {printf $fh "%#2.2x",$y/256};
	if($i<7) {print $fh ","}    
    }
}
#-------------------------------------------------------------------------------
# generate wavetable for waveform 2 (sine)
#-------------------------------------------------------------------------------
$sin1=1;
$cos1=0;
$sin2=0;
$cos2=0;
$sin3=0;
$cos3=0;
$sin4=0;
$cos4=0;
$sin5=0;
$cos5=0;
$sin6=0;
$cos6=0;
$sin7=0;
$cos7=0;

print $fh "\n\nwtab2:";
for($j=0;$j<128;$j++)
{
    print $fh "\n    .db ";
     for($i=0;$i<8;$i++)
    {
	$x=$i+8*$j;
	$y=0;
	$y+=$sin1*32767*sin($x*3.1416/512);
	$y+=$cos1*32767*cos($x*3.1416/512);
	$y+=$sin2*32767*sin($x*3.1416/(512/2));
	$y+=$cos2*32767*cos($x*3.1416/(512/2));
	$y+=$sin3*32767*sin($x*3.1416/(512/3));
	$y+=$cos3*32767*cos($x*3.1416/(512/3));
	$y+=$sin4*32767*sin($x*3.1416/(512/4));
	$y+=$cos4*32767*cos($x*3.1416/(512/4));
	$y+=$sin5*32767*sin($x*3.1416/(512/5));
	$y+=$cos5*32767*cos($x*3.1416/(512/5));
	$y+=$sin6*32767*sin($x*3.1416/(512/6));
	$y+=$cos6*32767*cos($x*3.1416/(512/6));
	$y+=$sin7*32767*sin($x*3.1416/(512/7));
	$y+=$cos7*32767*cos($x*3.1416/(512/7));
	if ($y<(-0.5)) {$y=abs($y)+32768};
	if (($y%256)<1) {printf $fh "0x00,"} else {printf $fh "%#2.2x,",$y%256};
	if (($y/256)<1) {printf $fh "0x00"} else {printf $fh "%#2.2x",$y/256};
	if($i<7) {print $fh ","}    
    }
}

#-------------------------------------------------------------------------------
# envelope is like e^(-x)
#-------------------------------------------------------------------------------
print $fh "\n\netab1:";
$end=256;
for($j=0;$j<64;$j++)
{
    print $fh "\n    .db ";
    for($i=0;$i<8;$i++)
    {
	$x=$i+8*$j;
	$y=65535*exp(-($x/$end*$fakt));
	if (($y%256)<1) {printf $fh "0x00,"} else {printf $fh "%#2.2x,",$y%256};
	if (($y/256)<1) {printf $fh "0x00"} else {printf $fh "%#2.2x",$y/256};
	if ($i<7) {print $fh ","};
    }	
}
print $fh "\n\n";


close($fh);

