Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
#!C:/Perl/bin/perl #use strict; use Win32; use Win32::Sound; use Win32::GUI; my %DEC; $DEC{'WAV'} = "temple.wav"; $DEC{'GUI_WIDTH'} = 640; $DEC{'GUI_HEIGHT'} = 480; $DEC{'GUI_HEIGHT_MIN'} = 300; $DEC{'GUI_WIDTH_MIN'} = 400; $DEC{'WAVGRAPH_X'} = 1; $DEC{'WAVGRAPH_Y'} = 150; $DEC{'WAVGRAPH_W'} = 540; $DEC{'WAVGRAPH_H'} = 165; $DEC{'PEN_GRAY'} = new Win32::GUI::Pen(-color => [ 125,125,125 ], -wid +th => 1); $DEC{'PEN_BLK'} = new Win32::GUI::Pen(-color => [ 0,0,0 ], -width => 1 +); $DEC{'BRUSH_GRAY'} = new Win32::GUI::Brush([ 125,125,125 ]); $DEC{'BRUSH_BLK'} = new Win32::GUI::Brush([ 0,0,0 ]); my $desk = Win32::GUI::GetDesktopWindow(); my $dw = Win32::GUI::Width($desk); my $dh = Win32::GUI::Height($desk); my $x = ($dw - $DEC{'GUI_WIDTH'}) / 2; my $y = ($dh - $DEC{'GUI_HEIGHT'}) / 2; my $MW = new Win32::GUI::Window(-left => $x, -top=> $y, -helpbutton => + 0, -menu => 0, -maximizebox => 0, -minimizebox => 0, -resizable => 1 +, -topmost => 0, -width => $DEC{'GUI_WIDTH'}, -height => $DEC{'GUI_HE +IGHT'}, -name => "Window", -text => "$ENV{'PROGRAM_NAME'}");# -intera +ctive => 0, -onMouseMove => \&MouseMove, -onMouseUp => \&MouseUp, -on +MouseDown => \&MouseDown); my $SoundFileGroup = $MW->AddGroupbox(-left => 7, -top => (30), -text +=> "Sound File ", -name => "SoundFileGroup",-height => 100, -width = +> 385); my $GraphGroup = $MW->AddGroupbox(-left => 7, -top => (140), -text => +"Sound Graph ", -name => "GraphGroup",-height => 265, -width => 385) +; my $PlotButton = $MW->AddButton(-left => 325, -top => 50, -name => 'Pl +otButton', -text => 'Graph'); my $ListenButton = $MW->AddButton(-left => 325, -top => 80, -name => ' +ListenButton', -text => 'Listen'); my $WavFile = $MW->AddTextfield(-name => "WavFile", -tabstop => 6, -au +tovscroll => 0, -text => "$DEC{'WAV'}", -sunken => 1, -left => 20, -t +op => 50, -width => 300, -height => 22, -multiline => 0); ##################EDIT ####################### my $DC = $MW->GetDC; $MW->Show(); Win32::GUI::DoEvents(); Win32::GUI::DoEvents(); Win32::GUI::Dialog(); sub ListenButton_Click{ &PlotButton_Click; my $left = $MW->GraphGroup->Left+4; my $top = $MW->GraphGroup->Top+15; my $width = $MW->GraphGroup->Width-10; my $height = ($MW->GraphGroup->Height-21); $DC->SelectObject($DEC{'PEN_BLK'}); my %WV = &DescribeWav($DEC{'WAV'}); my $LPS = int(($width/$WV{'Duration'})); $width = $LPS; $WAV = new Win32::Sound::WaveOut($DEC{'WAV'}); $WAV-> Play() or die "Play: $!"; for(my $cnt = 0; $cnt <= ($WV{'TotalSamples'});$cnt++){ my $at = $WAV->Position(); if ($WV{'nChannels'} > 1){$at = $at*2;} if ($WV{'nBitsPerSample'} > 8){$at = $at*2;} $WV{'at'} = $at; my $gper = int(($at*($MW->GraphGroup->Width-10))/($WV{'TotalSa +mples'}*$WV{'nBlockAlign'})); $DC->BeginPath(); $DC->MoveTo($left+$gper,$top); $DC->LineTo($left+$gper,$top+5); $DC->MoveTo($left+$gper,$top+$height-5); $DC->LineTo($left+$gper,$top+$height); $DC->EndPath(); $DC->StrokePath(); if ($WAV->Status() == 1){$cnt = $WV{'TotalSamples'}+1;} } $WAV->Reset(); Win32::GUI::DoEvents(); }######################################## end ListenButton_Click sub PlotWav{ my $wav = $_[0]; my $left = $_[1]; my $top = $_[2]; my $width = $_[3]; my $height = $_[4]; my $secbarheight = ($height*20)/200; my $subsecbarheight = ($height*10)/200; my %WAV = &DescribeWav($wav); $MW->GraphGroup->Text("$WAV{'FileName'} : $WAV{'FileDescription'} +: Samples=$WAV{'TotalSamples'} Dur=$WAV{'Duration'}"); $MW->InvalidateRect(1); Win32::GUI::DoEvents(); $DC->SelectObject($DEC{'PEN_GRAY'}); $DC->BeginPath(); $DC->MoveTo($left,$top); $DC->LineTo(($left+$width),$top); $DC->LineTo(($left+$width),($top+$height)); $DC->LineTo($left,($top+$height)); $DC->LineTo($left,$top); $DC->EndPath(); $DC->StrokePath(); ####### PLOT SECONDS BAR my $LPS = int(($width/$WAV{'Duration'})); for(my $sec = 0;$sec <= $WAV{'Duration'};$sec++){ $DC->BeginPath(); $DC->MoveTo(($left+($sec*$LPS)),$top); $DC->LineTo(($left+($sec*$LPS)),$top+$secbarheight); $DC->MoveTo(($left+($sec*$LPS)),$top+$height-$secbarheight); $DC->LineTo(($left+($sec*$LPS)),$top+$height); $DC->EndPath(); $DC->StrokePath(); } ####### PLOT SUBSECONDS BAR $DEC{'PEN_SUB'} = new Win32::GUI::Pen(-color => [ 200,200,200 ], - +width => 1); $DC->SelectObject($DEC{'PEN_SUB'}); for(my $sec = 0;$sec <= $WAV{'Duration'};$sec++){ for(my $subsec = 1;$subsec < 10;$subsec++){ my $asec = $sec+($subsec/10); if ($asec <= $WAV{'Duration'}){ $DC->BeginPath(); $DC->MoveTo(($left+($asec*$LPS)),$top+1); if ($asec =~ /\.5/){ $DC->LineTo(($left+($asec*$LPS)),$top+($subsecbarh +eight+($subsecbarheight/2))); $DC->MoveTo(($left+($asec*$LPS)),$top+$height-($su +bsecbarheight+($subsecbarheight/2))); $DC->LineTo(($left+($asec*$LPS)),$top+$height); }else{ $DC->LineTo(($left+($asec*$LPS)),$top+$subsecb +arheight+1); $DC->MoveTo(($left+($asec*$LPS)),$top+$height- +$subsecbarheight); $DC->LineTo(($left+($asec*$LPS)),$top+$height) +; } $DC->EndPath(); $DC->StrokePath(); } } } ####### END SECONDS BAR $DEC{'PEN_LEFT'} = new Win32::GUI::Pen(-color => [ 250,50,50 ] +, -width => 1); $DC->SelectObject($DEC{'PEN_LEFT'}); $DC->BeginPath(); $DC->MoveTo($left,$top+($height/2)); my $volume = 1;#0-1 my $SPS = ($LPS*$WAV{'Duration'}); my %INF; $INF{'file'} = $WAV{'FilePath'}; $INF{'start'} = &GetDataStart($WAV{'FilePath'}); $INF{'nBlockAlign'} = $WAV{'nBlockAlign'}; $INF{'nBitsPerSample'} = $WAV{'nBitsPerSample'}; for(my $x = 1;$x<=$width;$x=$x+1){ $INF{'sample'} = int(($WAV{'TotalSamples'}*$x)/$SPS); my ($alc,$arc) = &GetSample(%INF); my $lx = $alc; if ($INF{'nBitsPerSample'} == 8){$lx = int(($lx-128)*(($he +ight/4))/255);} if ($INF{'nBitsPerSample'} == 16){$lx = int($lx*(($height/ +2))/65335);} $DC->LineTo(($left+$x),$top+($height/4)+$lx); } $DC->EndPath(); $DC->StrokePath(); Win32::GUI::DoEvents(); ################ RIGHT CHANNEL $DEC{'PEN_RIGHT'} = new Win32::GUI::Pen(-color => [ 50,250,50 +], -width => 1); $DC->SelectObject($DEC{'PEN_RIGHT'}); $DC->BeginPath(); $DC->MoveTo($left,$top+($height/2)); my $volume = 1;#0-1 my $SPS = ($LPS*$WAV{'Duration'}); my %INFR; $INFR{'file'} = $WAV{'FilePath'}; $INFR{'start'} = &GetDataStart($WAV{'FilePath'}); $INFR{'nBlockAlign'} = $WAV{'nBlockAlign'}; $INFR{'BPS'} = $WAV{'nBitsPerSample'}; for(my $x = 1;$x<=$width;$x=$x+1){ $INFR{'sample'} = int(($WAV{'TotalSamples'}*$x)/$SPS); my ($alc,$arc) = &GetSample(%INFR); my $rx = $arc; if ($INF{'nBitsPerSample'} == 16){$rx = int($rx*(($height/ +2))/65335);} $DC->LineTo(($left+$x),$top+(($height/4)*3)+$rx); } $DC->EndPath(); $DC->StrokePath(); Win32::GUI::DoEvents(); }######################################## end PlotWav sub PlotButton_Click { $DEC{'PEN_L'} = new Win32::GUI::Pen(-color => [ 33,123,33 ], -widt +h => 1); $DEC{'PEN_R'} = new Win32::GUI::Pen(-color => [ 123,33,33 ], -widt +h => 1); $DEC{'WAV'} = $MW->WavFile->Text(); my %PLOT = @_; $MW->InvalidateRect(1); Win32::GUI::DoEvents(); undef $WAV; my $left = $MW->GraphGroup->Left+4; my $top = $MW->GraphGroup->Top+15; my $width = $MW->GraphGroup->Width-10; my $height = ($MW->GraphGroup->Height-21); my $secbarheight = ($height*20)/200; my $subsecbarheight = ($height*10)/200; &PlotWav($DEC{'WAV'},$left,$top,$width,$height); }######################################## end PlotButton_Click sub Window_Terminate { $DEC{'TERMINATING'} = 1; return -1; }######################################## end Window_Terminate sub Window_Resize { if ($MW->Width < $DEC{'GUI_WIDTH_MIN'}){$MW->Width($DEC{'GUI_WIDTH +_MIN'});} if ($MW->Height < $DEC{'GUI_HEIGHT_MIN'}){$MW->Height($DEC{'GUI_HE +IGHT_MIN'});} $DEC{'GUI_WIDTH'} = $MW->Width; $DEC{'GUI_HEIGHT'} = $MW->Height; $MW->SoundFileGroup->Width($DEC{'GUI_WIDTH'}-20); $MW->GraphGroup->Width($DEC{'GUI_WIDTH'}-20); $MW->GraphGroup->Height($DEC{'GUI_HEIGHT'}-180); }######################################## end Window_Resize sub DescribeWav{ my $file = $_[0]; my %WAV; my $file_size = int(-s "$file"); local $/ = \1; my $sp; my $rcnt; my $str; my $firChunkCnt = 0; my $headChunk = ""; my $dataChunk = ""; my $isDataChunk; my %chunks; $WAV{'FilePath'} = $file; $WAV{'FileName'} = $file; $WAV{'FileSize'} = $file_size; $WAV{'FileName'} =~ s/.*[\\|\/]+//; while ($sp <= $file_size){ open (FILE,$file); seek(FILE,$sp,0); while (my $li = <FILE>){ $rcnt++; $str .= $li; if ($rcnt == 12){ if (!$str =~ /RIFF.{4}WAVE/){print "Not a WAVE Chunk H +eader\n";return;} $str =~ s/RIFF(.{4})WAVE/$1/i; $str = ""; } if (($rcnt > 12)&&($li eq "f")&&(!$firChunkCnt)){$firChunk +Cnt = $rcnt;} if ($firChunkCnt){ $headChunk .= $li; if (length $headChunk == 23){ if ($headChunk =~ /fmt\W/){ $headChunk =~ s/^(....)(....)(..)(..)(....)(.. +.)(..)(..)/$1\|$2\|$3\|$4\|$5\|$6\|$7\|$8/; my($ckID,$nChunkSize,$wFormatTag,$nChannels,$n +SamplePerSec,$nAvgBytesPerSec,$nBlockAlign,$nBitsPerSample) = split(/ +\|/,$headChunk); $WAV{'nChunkSize'} = unpack("s",$nChunkSize); $WAV{'wFormatTag'} = unpack("v*",$wFormatTag); $WAV{'nChannels'} = unpack("v*",$nChannels); $WAV{'nSamplePerSec'} = unpack("v*",$nSamplePe +rSec); $WAV{'nAvgBytesPerSec'} = unpack("v*",$nAvgByt +esPerSec); $WAV{'nBlockAlign'} = int(unpack("H*",$nBlockA +lign)); $WAV{'nBitsPerSample'} = int(hex(unpack("H*",$ +nBitsPerSample))); if ($WAV{'wFormatTag'} == 1){my @mss = ("mono" +,"stereo");$WAV{'FileDescription'} = $WAV{'nBitsPerSample'}."bit ".$m +ss[$WAV{'nChannels'}-1]." ".($WAV{'nSamplePerSec'}/1000)."hz";} $headChunk = ""; $WAV{'VALID'} = 1; if ($WAV{'wFormatTag'} != 1){$WAV{'VALID'} = 0 +;} $sp = $file_size+1; $WAV{'DataChunkStart'} = ($WAV{'nChunkSize'}+$ +firChunkCnt+7)+8; last; } } } } close FILE; } $sp = int($WAV{'DataChunkStart'}-8); $rcnt = 0; $str = ""; open (FILE,$file); while ($sp < $file_size){ seek(FILE,$sp,0); while (my $li = <FILE>){ $rcnt++; $str .= $li; if ($rcnt > 8){ $str =~ s/(....)/$1\|/; my($name,$lg) = split(/\|/,$str,2); $lg = unpack("V",$lg); if (($name eq "data")&&(!$WAV{'SoundChunkStart'})){ $WAV{'SoundChunkStart'} = $sp+8; $WAV{'SoundChunkLength'} = $lg; $WAV{'TotalSamples'} = int($WAV{'SoundChunkLength' +}/$WAV{'nBlockAlign'}); $WAV{'Duration'} = $WAV{'TotalSamples'}/$WAV{'nSam +plePerSec'}; } $chunks{$name} = $lg.":".($rcnt+$sp); $rcnt = 0;$str = "";$sp = $sp+$lg+8;last; } } }close FILE; foreach my $li(keys %chunks){ $WAV{"Chunk$li"} = $chunks{$li}; $WAV{'TotalChunks'}++; } return %WAV; }############################################# end DescribeWav sub GetSample{ my %INF = @_; my $asp = $INF{'start'}+(($INF{'sample'}-1)*$INF{'nBlockAlign'}); local $/ = \1; open(FILE,$INF{'file'}); binmode FILE; seek(FILE,$asp,0); my $cnt; my $lis; while (my $li = <FILE>){ $lis .= $li; if (length $lis >= $INF{'nBlockAlign'}){ my ($lc,$rc); #1=8 bit mono,2=8bitstereo or 16bitmono,4=16bitstereo if ($INF{'nBlockAlign'} == 1){ $lc = hex(unpack("H*",$lis));} if ($INF{'nBlockAlign'} == 2){ if ($INF{'nBitsPerSample'} == 16){ $lc = unpack("s",$lc); }else{ ($lc,$rc) = unpack('a1a1', $lis); $lc = hex(unpack("H*",$lc)); $rc = hex(unpack("H*",$rc)); } }############################### if ($INF{'nBlockAlign'} == 4){ ($lc,$rc) = unpack('a2a2', $lis); $lc = unpack("s",$lc);$rc = unpack("s",$rc); }############################### close FILE; local $/ = \n; if (!$lc){$lc = 0;} if (!$rc){$rc = 0;} return $lc,$rc; } } }################################ end GetSample sub GetDataStart{ my $file = $_[0]; my $str; local $/ = \1; open(FILE,$file); binmode FILE; seek(FILE,0,0); while (my $li = <FILE>){ $str .= $li; if ($str =~ /data$/){ close FILE; local $/ = \n; return length($str)+4; } } close FILE; }################################ end GetDataStart

In reply to Plot a 8/16bit wav file with Win32::GUI by true

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (2)
As of 2023-06-04 04:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How often do you go to conferences?






    Results (17 votes). Check out past polls.

    Notices?