#!/usr/local/bin/perl $|=1; $firstfile = shift; $secondfile = shift; $resultfile = shift; $threshold = shift || 0; # noise gate threshold at beginning and end $bytes = 100; # amount of header byte to read $wav1 = $firstfile . ".copy"; $wav2 = $secondfile . ".copy"; if (!(-e $firstfile)) { print "The file \"$firstfile\" does not exist!\n"; exit; } if (!(-e $secondfile)) { print "The file \"$secondfile\" does not exist!\n"; exit; } if (($threshold < 0) || ($threshold > 32000) || ($threshold =~ /\D/g)) { print "Invalid threshold value \"$threshold\""; print " It has to be between 0 and 32,000. I set it to 0 now.\n" } # copy original files `cp $firstfile $wav1`; `cp $secondfile $wav2`; &modify_second; &modify_first; # concatenate them `cat $wav2 \>\> $wav1`; # copy to result file `cp $wav1 $resultfile`; #delete copy of second; unlink $wav1; unlink $wav2; print "Deleted copies of the files. The resultfile is $resultfile.\nDone! Seeya...\n"; sub modify_second { $old_rs = $/; open(SECOND, "<$secondfile"); undef $/; $second_content = ; #so-called slurp mode... close SECOND; chomp $second_content; # do i need that? $/ = $old_rs; print "OK, let's start...\n\n"; print "----------SECOND FILE--------\n"; print "Let's look for the data length.\n"; $posi = -1; for ($i=0; $i<=($bytes-4); $i++) { $cha = substr($second_content,$i,1); if ($cha eq 'd'){ $cha = substr($second_content,$i+1,1); if ($cha eq 'a') { $cha = substr($second_content,$i+2,1); if ($cha eq 't') { $cha = substr($second_content,$i+3,1); if ($cha eq 'a') { $posi = $i + 4; last; } } } } } print " \"data\" starts at position $posi\n"; $second_data_length = substr($second_content,$posi,4); # read out the 4 bytes $second_databytes_length = unpack("l", $second_data_length); #transform to numbers print " Data bytes length: ---$second_databytes_length---\n"; $increase = $second_databytes_length; # that's the amount the second file will be longer substr($second_content,0,($posi+4)) = ''; # delete all after 'data' +4 bytes # &test_prog; &trunc_beginning; &trunc_end; print "The total length of the second file is now $increase bytes.\n"; open(COPYSECOND, ">$wav2"); print COPYSECOND $second_content; close COPYSECOND; } sub modify_first { open(FILE, "+<$wav1"); sysread(FILE, $content, $bytes); print "---------FIRST FILE, TOTAL-----------\n"; print "Let's look for the total length.\n"; $total_length = substr($content,4,4); $bytes_length = unpack("l", $total_length); print " Total byte length: ---$bytes_length---\n"; $bytes_length = $bytes_length + $increase; print " Total byte length increased to ---$bytes_length---\n"; $substring = pack("l", $bytes_length); substr($content,4,4) = $substring; # write back the modified substring print " Replaced the total length field!\n"; print "----------FIRST FILE, DATA------------\n"; print "Let's look for the data length.\n"; $pos = -1; for ($i=0; $i<=($bytes-4); $i++) { $ch = substr($content,$i,1); #print "-----char $i: $ch\n"; if ($ch eq 'd'){ $ch = substr($content,$i+1,1); if ($ch eq 'a') { $ch = substr($content,$i+2,1); if ($ch eq 't') { $ch = substr($content,$i+3,1); if ($ch eq 'a') { $pos = $i + 4; last; } } } } } print " \"data\" starts at position $pos\n"; $data_length = substr($content,$pos,4); $databytes_length = unpack("l", $data_length); print " Data byte length: ---$databytes_length---\n"; $databytes_length = $databytes_length + $increase; print " Data byte length increased to ---$databytes_length---\n"; $substring = pack("l", $databytes_length); substr($content,$pos,4) = $substring; print " Replaced the data length field!\n"; seek(FILE, 0, 0); syswrite(FILE,$content,$bytes); close FILE; } # end of sub modify_first sub trunc_beginning { # Look for the first bytes above threshold print "Truncating beginning...\n"; $cutoff_beginning = 0; for ($i=0; $i <=$increase-4; $i = $i+4){ $sound_1 = substr($second_content,$i,2); $sound_2 = substr($second_content,$i+2,2); $sound_1 = unpack("v",$sound_1); $sound_2 = unpack("v",$sound_2); if ($sound_1 >32767) { $sound_1 = 65536 - $sound_1 ;} if ($sound_2 >32767) { $sound_2 = 65536 - $sound_2 ;} if ((($sound_1 + $sound_2)/2) > $threshold) { print " Found levels above threshold: L $sound_1, R $sound_2, byte $i of $increase\n"; $cutoff_beginning = $i; last; } } print " I will cut off the first $cutoff_beginning bytes.\n"; substr($second_content,0,$cutoff_beginning) = '';# take off the silent part at the beginning $increase = $increase - $cutoff_beginning; # adjust the length of the string } # end of sub trunc_beginning sub trunc_end { # Look for the last bytes above threshold print "Truncating end...\n"; $cutoff_end = 0; for ($i=$increase-4; $i >=0; $i = $i-4){ $sound_1 = substr($second_content,$i,2); $sound_2 = substr($second_content,$i+2,2); $sound_1 = unpack("v",$sound_1); $sound_2 = unpack("v",$sound_2); if ($sound_1 >32767) { $sound_1 = 65536 - $sound_1 ;} if ($sound_2 >32767) { $sound_2 = 65536 - $sound_2 ;} if ((($sound_1 + $sound_2)/2) > $threshold) { print " Found levels above threshold: L $sound_1, R $sound_2, byte $i of $increase\n"; $cutoff_end = $i; last; } } $how_much_truncate = $increase - $cutoff_end; print " I will cut off the last $how_much_truncate bytes.\n"; substr($second_content,-$how_much_truncate,$how_much_truncate) = ''; # truncate at end $increase = $increase - $how_much_truncate; # adjust the length of the string } # end of sub trunc_end sub test_prog { # TEST PROGRAM $start =3800; $limit = $start + 200; for ($i=$start; $i <=$limit; $i = $i+4){ $sound_1 = substr($second_content,$i,2); $sound_2 = substr($second_content,$i+2,2); $sound_1 = unpack("v",$sound_1); $sound_2 = unpack("v",$sound_2); if ($sound_1 >32767) { $sound_1 = 65536 - $sound_1 ;} if ($sound_2 >32767) { $sound_2 = 65536 - $sound_2 ;} print "Byte $i: L $sound_1\tR $sound_2\n"; } } # end of test_prog