#!/usr/bin/perl use warnings; use strict; use Tk qw/MainLoop tkinit DoOneEvent exit DONT_WAIT ALL_EVENTS/; use Audio::DSP; $| = 1; my $sample_rate = 8000; my $channels = 1; my $format = AFMT_S16_LE; my $buffer = 1; my $dsp = new Audio::DSP(buffer => $buffer, channels => $channels, format => $format, rate => $sample_rate); $dsp->init() || die $dsp->errstr(); ############################################################ my $freq_adj = .1; my $vol = .5; my @speeds = (8000,11025,22050,44100); ############################################################## my $mw = tkinit; my $stop = 0; my $adjust = 10000; $mw->Scale(-from => 0, -to => 10000, -variable => \$adjust, -orient => 'horizontal', -showvalue => 1, -command => sub { $freq_adj = $adjust/10000 + .01 ; $mw->DoOneEvent( DONT_WAIT | ALL_EVENTS ); })->pack; my $volume = 50; $mw->Scale(-from => 0, -to => 100, -variable => \$volume, -orient => 'horizontal', -showvalue => 1, -command => sub { $vol = $volume/100 + .01 ; $mw->DoOneEvent( DONT_WAIT | ALL_EVENTS ); })->pack; $mw->Button( -text => 'Start', -command => sub { $stop = 0; &generate }, )->pack(); $mw->Button( -text => 'Stop', -command => sub { $stop = 1; }, )->pack(); $mw->Button( -text => 'Speed', -command => sub { push @speeds, shift @speeds; $dsp->speed($speeds[0]); } )->pack(); $mw->Button( -text => 'Quit', -command => sub {$stop = 0;$dsp->close; exit(0) }, )->pack(); #MainLoop; $mw->DoOneEvent( MainLoop ); ################################################# sub generate{ while(1){ make_tone($freq_adj, $vol); if($stop){return}; } } sub make_tone { my $rad = 0; my ($freq_adj, $vol) = @_; while ( $rad < 6.283 ){ if($stop){last} $rad += $freq_adj; my $raw = ($vol*32768) * sin($rad); #max times my $num = pack( 'V', $raw ); $dsp->dwrite($num); $mw->DoOneEvent( DONT_WAIT | ALL_EVENTS ); } }