#!/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);