$pi = 3,141592653589793238462643383279502884197169399375105820974944592; sub drumb{ my ($gate, $volume, ) = @_; undef @line1; undef @line2; push @line1, envelope( 1, 30, nois(100, $gate/3, $volume, )); push @line2, envelope( 1, 5, sine( 50, $gate, $volume, 1, )); return mix('line1', 1, 'line2', 1, 0, ); } sub snarb{ my ($gate, $volume, ) = @_; undef @line1; undef @line2; push @line1, envelope( 1, 30, nois(100, $gate, $volume, )); # push @line2, envelope( 2, 1, nois(100, $gate, $volume/4, )); return mix('line1', 1, 'line2', 1, 0, ); } sub mix{ my ($list1, $lev1, $list2, $lev2, $offset, ) = @_; print "\nmixing $list1 and $list2 ... " if $debug; $offset*=$samplerate; my $o; my @output; for$o(0..$offset-1){ push @output, ${$list1}[$o]*$lev1; } for$o($offset..$offset+$#{$list2}){ push @output, ${$list1}[$o]*$lev1+${$list2}[$o-$offset]*$lev2; } if ($#$list1>($#$list2+$offset)){ for$o($offset+$#{$list2}..$#{$list1}){ push @output, ${$list1}[$o]*$lev1; } } print "ok." if $debug; return @output; } sub envelope{ my ($env, $rate, @input, ) = @_; $rate = $env unless $rate; my @output; my $multi = 1; my $s; for$s(0...$#input){ $multi = $#input/($#input+$s*$rate) if $env==1; $multi = ($#input-$s/$rate)/$#input if $env==2; $multi = (($#input-$s)/($#input))**(1/$rate) if $env==3; push @output, $input[$s]*$multi; } return @output; } sub smooth{ my ($rate, @output, ) = @_; my $s; for(1..$rate){ my @temp = @output; undef @output; push @output, $temp[0]; for$s(1...$#temp){ push @output, ($temp[$s]*1/2) + ($temp[$s-1]*1/2); } } return @output; } sub multiply{ my ($list1, $list2, ) = @_; @list1=@$list1; @list2=@$list2; my @output; my $s; for$s(0...$#list1){ push @output, sqrt(abs($list1[$s])) * sqrt(abs($list2[$s])) * -1 if ($list1[$s]+$list2[$s]<0); push @output, sqrt(abs($list1[$s])) * sqrt(abs($list2[$s])) unless ($list1[$s]+$list2[$s]<0); } return @output; } sub nois{ my($freq, $gate, $volume, ) = @_; print "\n NOIS: freq: $freq gate: $gate volume: $volume" if $debug; $freq*=64; my @samples; my $s; for$s(0..$gate*$samplerate){ push @samples, int rand(2*$volume)-$volume; } return @samples; } sub squa{ my($freq, $gate, $volume, $kind, ) = @_; print "\n SQUA: freq: $freq gate: $gate volume: $volume" if $debug; $kind=1/2 unless $kind; my @samples; my $lung=$samplerate/$freq; my $slope=$volume/$lung; my $count; my $s; my $volumex=$volume; for$s(0..$gate*$samplerate){ $count=0 if $count>$lung; push @samples, $volume if $count<$lung*$kind; push @samples, -$volume unless $count<$lung*$kind; $count++; } return @samples; } sub sine{ my($freq, $gate, $volume, $kind, ) = @_; print "\n SINE: freq: $freq gate: $gate volume: $volume" if $debug; $freq *= 1030/1000 if $kind; ## buono a 880hz # $freq *= 10255/10000 if $kind; ## buono a 440hz # $freq *= 1047/1000 if $kind; ## perfetto a 110hz my @samples; my $lung=$samplerate/$freq; my $count; my $s; for$s(0..$gate*$samplerate){ $count=0 if $count>=$lung; push @samples, $volume*sin(2*$pi*$count/$lung) unless $kind; push @samples, $volume*sin(2*$pi*$s/$lung) if $kind; $count++; } return @samples; } sub sawt{ my($freq, $gate, $volume, $kind, ) = @_; print "\n SAWT: freq: $freq gate: $gate volume: $volume" if $debug; my @samples; my $lung=$samplerate/$freq; my $slope=$volume/$lung; my $count; my $s; my $volumex=$volume; if ($kind == 1){ ############################# montagne $volumex = 0; my $way = +1; for$s(0..$gate*$samplerate){ push @samples, $volumex; $way *= -1 if abs($volumex) >= abs($volume); $volumex = $volume if $volumex > $volume; $volumex = -$volume if $volumex < -$volume; $volumex += 4*$way*$slope; } }else{ ############################# sega $volumex = 0; for$s(0..$gate*$samplerate){ $volumex += 2*$slope; push @samples, $volumex; $volumex = -$volume if abs($volumex) > abs($volume); } } return @samples; } sub sile{ my($gate, ) = @_; print "\n SILE: gate: $gate " if $debug; my @samples; for(0..$gate*$samplerate){ push @samples, '0'; } return @samples; } sub header{ $block = $canali*$bits/8; $samplestream = $durata*$samplerate*$block; $chunksize = $samplestream+44; $C[0] = chr hex '52'; # R $C[1] = chr hex '49'; # I $C[2] = chr hex '46'; # F $C[3] = chr hex '46'; # F #$C[4] = chr hex '2c'; # = chunk size (2C 00 00 00 + i dati) #$C[5] = chr hex '00'; # #$C[6] = chr hex '00'; # #$C[7] = chr hex '00'; # for(four($chunksize)){ push @C, chr hex $_; } $C[8] = chr hex '57'; # W $C[9] = chr hex '41'; # A $C[10] = chr hex '56'; # V $C[11] = chr hex '45'; # E $C[12] = chr hex '66'; # f $C[13] = chr hex '6d'; # m $C[14] = chr hex '74'; # t $C[15] = chr hex '20'; # $C[16] = chr hex '10'; # = subchunk size = 16 $C[17] = chr hex '00'; # $C[18] = chr hex '00'; # $C[19] = chr hex '00'; # $C[20] = chr hex '01'; # = audio format = 1 (PCM) $C[21] = chr hex '00'; # #$C[22] = chr hex '01'; # = channels = 1 (stereo=2) #$C[23] = chr hex '00'; # for(two($canali)){ push @C, chr hex $_; } #$C[24] = chr hex '44'; # = sample rate = 44100 #$C[25] = chr hex 'ac'; # #$C[26] = chr hex '00'; # #$C[27] = chr hex '00'; # for(four($samplerate)){ push @C, chr hex $_; } #$C[28] = chr hex '88'; # = byte rate = 88200 (stereo=x2) #$C[29] = chr hex '58'; # #$C[30] = chr hex '01'; # #$C[31] = chr hex '00'; # for(four($samplerate*$block)){ push @C, chr hex $_; } #$C[32] = chr hex '02'; # = block align = 2 (stereo=4) #$C[33] = chr hex '00'; # for (two($block)){ push @C, chr hex $_; } $C[34] = chr hex '10'; # = bits per sample = 16 $C[35] = chr hex '00'; # $C[36] = chr hex '64'; # d $C[37] = chr hex '61'; # a $C[38] = chr hex '74'; # t $C[39] = chr hex '61'; # a #$C[40] = chr hex '88'; # = subchunk size = 2 x sample (i dati) #$C[41] = chr hex '58'; # #$C[42] = chr hex '01'; # #$C[43] = chr hex '00'; # for (four($samplestream)){ push @C, chr hex $_; } } sub stampa{ my $filename = shift; $filename = 'test-auto.wav' unless $filename; print "\n\nprinting samples ... " if $debug; my $tappeto = $durata*$samplerate; my $t; my @carpet; my $sample; my $s; for$t(0..$tappeto-1){ # push @carpet, 0; # per riempire tutto lo spazio dati con zeri. $sample=$left[$t]; $sample=65535+$sample if $sample<0; # $sample=$carpet[$t] unless $sample; $sample=0 unless $sample; for $s(two($sample)){ push @C, chr hex $s; } if ($canali==2){ $sample=$righ[$t]; $sample=65535+$sample if $sample<0; # $sample=$carpet[$t] unless $sample; $sample=0 unless $sample; for $s(two($sample)){ push @C, chr hex $s; } } } print "$filename ... " if $debug; open OUT,">$filename"; binmode OUT; print OUT join undef, @C; close OUT; print "done!\n" if $debug; } sub four{ my $n=shift; my $r= sprintf "%x", $n; my $z=8-length($r); my $x; for$x(1..$z){ $r="0".$r; } my @four=(substr($r, 6, 2), substr($r, 4, 2), substr($r, 2, 2), substr($r, 0, 2), ); return @four; } sub two{ my $n=shift; my $r= sprintf "%x", $n; my $z=4-length($r); my $x; for$x(1..$z){ $r="0".$r; } my @two=(substr($r, 2, 2), substr($r, 0, 2), ); return @two; } ############################# sub d{ # ############################# my $dado = shift; # return int rand($dado)+1; # } # ############################# kanakfecit; __END__