use Win32::Sound; $displayWave = 1; $range = 256/39; $virtlim = 47; $step = 24; $midofc = 20; @extremes = (0,0); %FqC = ('a', [55,110,220,440,880,1760], 'as',[58.270,116.541,233.082,466.164,932.328,1864.655], 'b', [61.735,123.471,246.942,493.883,987.767,1975.533], 'c', [65.406,130.813,261.626,523.251,1046.502,2093.005], 'cs',[69.296,138.591,277.183,554.365,1108.731,2217.461], 'd', [73.416,146.832,293.665,587.330,1174.659,2349.318], 'ds',[77.782,155.563,311.127,622.254,1244.508,2489.016], 'e', [82.407,164.814,329.628,659.255,1318.510,2637.020], 'f', [87.307,174.614,349.228,698.456,1396.913,2793.826], 'fs',[92.499,184.997,369.994,739.989,1479.978,2959.955], 'g', [97.999,195.998,391.995,783.991,1567.982,3135.963], 'gs',[103.826,207.652,415.305,830.609,1661.219,3322.438], 'p',[0,0,0,0,0,0] ); %def = ('octav', 3, 'frac', 4, 'paus', 64); print "Welcome to Perl Music Player V1 by Igor A. Rylov\n". "acmecode.com\n\n\n\tPlaying '$ARGV[0]' file.\n"; open(MUS, "$ARGV[0]"); @notes = (); while(){ $_ =~ s/[\n\r\f\cM]+$//; $_ =~ tr/#/s/; $_ = lc($_); @notes = (@notes, split(/\s+/, $_)); } close(MUS); # Create the object $WAV = new Win32::Sound::WaveOut(44100, 8, 2); $data = ""; $osc = 0; foreach $note (@notes){ ($note, $frac) = split('/', $note); $note =~ s/(\d)$//; $octav = $1; $octav = $def{'octav'} if($octav eq ''); $frac = $def{'paus'} if($frac eq '' && $note eq 'p'); $frac = $def{'frac'} if($frac eq '' || $frac eq 0); $counter = 0; $increment = $FqC{$note}[$octav]/44100; $label = (uc($note))."($octav) = $FqC{$note}[$octav]; ".(1/$frac)." Second; Step = $step\n"; # Generate 44100 samples ( = 1 second) $st = time; for $i (1..(44100/$frac)){ # Calculate the pitch # (range 0..255 for 8 bits) $v = ($note eq 'p')?(0):(sin($counter/2*3.14) * 128 + 128); $extremes[0] = $v if($extremes[0] > $v); $extremes[1] = $v if($extremes[1] < $v); if($displayWave){ if(($osc % ($virtlim * $step)) == 0){ system(cls); print $label; } if(($osc % $step) == 0){ print ' ' x (40 - $midofc + ($v/$range)); print "X\n"; } } ++$osc; # "pack" it twice for left and right $data .= pack("cc", $v, $v); $counter += $increment; } $newt = (time - $st); $step = $newt * $frac if($step == 1); } print "\n\nExtremes: $extremes[0] <=> $extremes[1]\n\n"; $WAV->Load($data); # get it $WAV->Write(); # hear it 1 until $WAV->Status(); # wait for completion # $WAV->Save("sinus.wav"); # write to disk $WAV->Unload(); # drop it