#!/usr/local/bin/perl -Tw # The indentation is sometimes very bad. Tell Xemacs the problem :) use CGI::Carp qw( fatalsToBrowser ); use CGI qw(:standard); use Benchmark; use English; use Getopt::Long; use File::Basename; use lib ("../Translation"); use Translation ('load', 'translate', 'language'); use Config; # signal stuff #%ENV = (); $ENV{'PATH'} = ""; sub handler { local($sig) = @_; $signb++; print "
Caught a SIG$sig signal : $signb
\n"; } GetOptions("configfile=s" => \$configurationFile, "messages=s" => \$messagesFile); $globalBegin = new Benchmark; $imagesPath = ""; $configurationFile = ($configurationFile) ? $configurationFile :"../etc/sequencesHTML.conf"; $messagesFile = ($messagesFile) ? $messagesFile : "../etc/messages.conf" ; %confParameters = readTheConfigurationFile($configurationFile); # I insert a line break if the sequences are too long # for a good printing in A4 paper. $lineBreakLimit = 7; $query = new CGI; param(-Name=>'Defaults', -Value=>'1') unless(param); #reading if the user wants to change the language. param(-Name=>'Language',-value=>"English") if(defined(param(-Name=>'EnglishImage.x'))); param(-Name=>'Language',-value=>"Francais") if(defined(param(-Name=>'FrenchImage.x'))); $corpus = load($messagesFile); $corpus->language(param(-Name=>'Language')) if (defined(param(-Name=>'Language'))); $| = 1; print header(-expires=>'+1h'); foreach $compression (qw(zip gz bz2 none)){ my(@command,$command,$configCompression,$configExtension); if ((defined(param(-Name=>'CompressionStyle'))) and (param(-Name=>'CompressionStyle') eq $compression)){ unshift @rollCompresion, $compression; }else{ push @rollCompresion, $compression; }; $configCompression = "${compression}Compression"; $configExtension = "${compression}Extension"; if ((defined($confParameters{$configCompression}))){ @command = split(/\s+/, $confParameters{$configCompression}); $command = $command[0]; } if ((defined($confParameters{$configCompression})) and (-x $command)) { $compression{'command'}{${compression}} = $confParameters{$configCompression} . " "; $compression{'label'}{${compression}} = $corpus->translate(" " . ${compression}); $compression{'available'}{${compression}} = 1; $compression{'extension'}{${compression}} = $confParameters{$configExtension}; }else{ $compression{'available'}{${compression}} = 0; } } while (@rollCompresion){ $compression = shift(@rollCompresion); if ($compression{'available'}{${compression}}){ param(-Name=>'CompressionStyle',-value=>$compression); $compression{'selected'}=$compression; last; }; } unless (@rollCompresion){ $compression{'selected'}='not available'; $compression{'label'}{'not available'} = $corpus->translate(' not available'); } # Default values if (param(-Name=>'Defaults')) { $saveLanguage = param(-Name=>'Language') if param(-Name=>'Language'); # Defaults are defautls ! So an easy way : CGI::delete_all(); param(-Name=>'CompressionStyle',-value=>$compression{'selected'}); #param(-Name=>'Filter',-value=>'yes') unless param(-Name=>'Filter'); param(-Name=>'Tempo',-value=>'320') unless param(-Name=>'Tempo'); param(-Name=>'Midi',-value=>'yes') unless param(-Name=>'Midi'); param(-Name=>'Graphics',-value=>'yes') unless param(-Name=>'Graphics'); param(-Name=>'Parrot',-value=>'yes') unless param(-Name=>'Parrot'); param(-Name=>'Repeat', -Value=>'2') unless param(-Name=>'Repeat'); param(-Name=>'Right Hand',-value=>'R') unless param(-Name=>'Right Hand'); param(-Name=>'Left Hand',-value=>'L') unless param(-Name=>'Left Hand'); param(-Name=>'Bass Drum',-value=>'O') unless param(-Name=>'Bass Drum'); param(-Name=>'Click',-value=>'K') unless param(-Name=>'Click'); param(-Name=>'ClickTimes',-value=>' 1 ') unless param(-Name=>'ClickTimes'); param(-Name=>'RuleR',-value=>'R 2') unless param(-Name=>'RuleR'); param(-Name=>'RuleL',-value=>'L 2') unless param(-Name=>'RuleL'); param(-Name=>'RuleO',-value=>'O 1') unless param(-Name=>'RuleO'); param(-Name=>'RuleH',-value=>'H 1') unless param(-Name=>'RuleH'); param(-Name=>'RuleS',-value=>'S 1') unless param(-Name=>'RuleS'); param(-Name=>'OppositeR',-value=>'R L') unless param(-Name=>'OppositeR'); param(-Name=>'OppositeL',-value=>'L R') unless param(-Name=>'OppositeL'); param(-Name=>'OppositeO',-value=>'O O') unless param(-Name=>'OppositeO'); param(-Name=>'OppositeH',-value=>'H O') unless param(-Name=>'OppositeH'); param(-Name=>'OppositeS',-value=>'S S') unless param(-Name=>'OppositeS'); param(-Name=>'InstrR',-value=>'56') unless param(-Name=>'InstrR'); param(-Name=>'InstrL',-value=>'40') unless param(-Name=>'InstrL'); param(-Name=>'InstrH',-value=>'44') unless param(-Name=>'InstrH'); param(-Name=>'InstrO',-value=>'36') unless param(-Name=>'InstrO'); param(-Name=>'InstrK',-value=>'53') unless param(-Name=>'InstrK'); param(-Name=>'VolR',-value=>'63') unless param(-Name=>'VolR'); param(-Name=>'VolL',-value=>'63') unless param(-Name=>'VolL'); param(-Name=>'VolH',-value=>'63') unless param(-Name=>'VolH'); param(-Name=>'VolO',-value=>'63') unless param(-Name=>'VolO'); param(-Name=>'VolK',-value=>'63') unless param(-Name=>'VolK'); param(-Name=>'Length', -Value=>'4') unless param(-Name=>'Length'); param(-Name=>'OutputStyle',-value=>' score') unless param(-Name=>'OutputStyle'); ($saveLanguage) ? param(-Name=>'Language',-value=>"$saveLanguage") : param(-Name=>'Language',-value=>"English"); } # Are the input values correct ? $query->delete('Right Hand') unless (param(-Name=>'Right Hand') and (param(-Name=>'Right Hand') =~ m/^R?$/)); $query->delete('Left Hand') unless (param(-Name=>'Left Hand') and param(-Name=>'Left Hand')=~ m/^L?$/); $query->delete('Bass Drum') unless (param(-Name=>'Bass Drum') and param(-Name=>'Bass Drum')=~ m/^O?$/); $query->delete('Hit Hat') unless (param(-Name=>'Hit Hat') and param(-Name=>'Hit Hat')=~ m/^H?$/); $query->delete('Silence') unless (param(-Name=>'Silence') and param(-Name=>'Silence')=~ m/^S?$/); param(-Name=>'RuleR',-value=>'R 0') unless param(-Name=>'RuleR')=~ m/^R (1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)$/; param(-Name=>'RuleL',-value=>'L 0') unless param(-Name=>'RuleL')=~ m/^L (1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)$/; param(-Name=>'RuleO',-value=>'O 0') unless param(-Name=>'RuleO')=~ m/^O (1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)$/; param(-Name=>'RuleH',-value=>'H 0') unless param(-Name=>'RuleH')=~ m/^H (1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)$/; param(-Name=>'RuleS',-value=>'S 0') unless param(-Name=>'RuleS')=~ m/^S (1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)$/; param(-Name=>'OppositeR',-value=>'R L') unless param(-Name=>'OppositeR')=~ m/^R (R|L|H|O|S)$/; param(-Name=>'OppositeL',-value=>'L R') unless param(-Name=>'OppositeL')=~ m/^L (R|L|H|O|S)$/;; param(-Name=>'OppositeO',-value=>'O H') unless param(-Name=>'OppositeO')=~ m/^O (R|L|H|O|S)$/;; param(-Name=>'OppositeH',-value=>'H O') unless param(-Name=>'OppositeH')=~ m/^H (R|L|H|O|S)$/;; param(-Name=>'OppositeS',-value=>'S S') unless param(-Name=>'OppositeS')=~ m/^S (R|L|H|O|S)$/;; param(-Name=>'Length',-value=>'0') unless param(-Name=>'Length')=~ m/^(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)$/; param(-Name=>'OutputStyle',-value=>' score') unless param(-Name=>'OutputStyle')=~ m/^( caracter| score)$/; param(-Name=>'Filter', -value=>'no') if (param(-Name=>'OutputStyle') eq " caracter"); param(-Name=>'Tempo', -value=>'2047') if (param(-Name=>'Tempo') > 2047); # Now, they are ! $doFilter = (defined(param(-Name=>'Filter')) and param(-Name=>'Filter') eq 'yes') ? 'yes' : 'no'; print start_html(-Title=>$corpus->translate('Drum Patterns, The infinite work !'), -Author=>'lamiral@mail.dotcom.fr', -Meta=>{'keywords'=>$corpus->translate('Drum, Sequence, Pattern, Score, Generator, Recursion, Lamiral, GNU, Open source software, GPL, Linux, Perl, CGI'), 'copyright'=> "Gnu Public Licence, copyleft May 1998 gilles lamiral"}, -BGCOLOR=>'#c0c0c0' ),"\n"; defined $Config{sig_name} or die "No signals ?"; $i = 0; foreach $name (split(' ', $Config{sig_name})) { $sig{$name} = $i; $sig{$i} = $name; #print "SIG$name = $i
\n"; $i++; } #$SIG{QUIT} = \&handler; #$SIG{PIPE} = \&handler; #print "

$$

\n"; #print "

select: $compression{'selected'}

\n"; $refCompressionLablels = $compression{'label'}; #print keys(%$refCompressionLablels), "
\n"; # I need to use "CGI::center" instead of "center". Is it a CGI bug ? # It seems to be ... #print dump,"\n"; #foreach $env (keys(%ENV)) { # print "$env:", $ENV{$env}, "
\n"; #} print startform, "
\n", # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), # Go to the home page a( {-href=>$corpus->translate('../index-en.html')}, img({-alt=>$corpus->translate('Back'), -src=>$corpus->translate('../images/forTheCGI/Home.gif'), -border=>"0",} ) ), # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), a( {-href=>$corpus->translate('../doc/english/DrumPatterns-Doc.html')}, img({-alt=>$corpus->translate('Documentation'), -src=>$corpus->translate('../images/forTheCGI/Documentation.gif'), -border=>"0",} ) ), # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), hidden(-Name=>'Language', -Value=>param(-Name=>'Language')), # A link to the English interface image_button(-alt=>$corpus->translate('English'), -Name=>'EnglishImage', -src=>$corpus->translate('../images/forTheCGI/English.gif'), -border=>'0', ), # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), # A link to the French interface image_button(-alt=>$corpus->translate('French'), -Name=>'FrenchImage', -src=>$corpus->translate('../images/forTheCGI/French.gif'), -border=>'0', ), # A blank img({-alt=>' ', -src=>'../images/forTheCGI/blank.gif'}), "
", "\n
", "
", "\n", "\n", "\n
", submit(-Name=>'Go', -Value=>$corpus->translate("Go !") ), "\n", reset(-Value=>$corpus->translate("Cancel")), "\n", submit(-Name=>'Defaults', -Value=>$corpus->translate("Defaults") ), "\n
", "\n
", "\n
", "\n\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n","","","","","
", $corpus->translate('Configuration'), "\n
", checkbox(-Name=>'Graphics', -value=>'yes', -label=>$corpus->translate(' Graphics') ), "\n", checkbox(-Name=>'Midi', -value=>'yes', -label=>$corpus->translate(' Midi') ), "\n
", "\n", $corpus->translate('Length'), "\n", $corpus->translate('Output'), "\n", $corpus->translate('Filter'), "\n", $corpus->translate('Save'), "\n", $corpus->translate('Repeat'), "\n", $corpus->translate('Compress'), "\n", $corpus->translate('Tempo'), "\n
", "\n", popup_menu(-name=>'Length', -Values=>['0','1','2','3','4','5','6','7','8', '9','10','11','12','13','14','15','16']), "\n", radio_group(-name=>'OutputStyle', -Values=>[' score', ' caracter'], -labels=>{' score'=>$corpus->translate(' score'), ' caracter'=>$corpus->translate(' letters') }, -linebreak=>'yes'), "\n",checkbox(-Name=>'Filter', -value=>'yes', -label=>$corpus->translate(' Loops') ), "\n", a({href=>CGI::self_url}, $corpus->translate("Config"), ), "\n", popup_menu(-name=>'Repeat', -Values=>['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32' ], -Labels=>{'1'=>'1', '2'=>'2', '3'=>'3', '4'=>'4', '5'=>'5', '6'=>'6', '7'=>'7', '8'=>'8', '9'=>'9', '10'=>'10', '11'=>'11', '12'=>'12', '13'=>'13', '14'=>'14', '15'=>'15', '16'=>'16', '17'=>'17', '18'=>'18', '19'=>'19', '20'=>'20', '21'=>'21', '22'=>'22', '23'=>'23', '24'=>'24', '25'=>'25', '26'=>'26', '27'=>'27', '28'=>'28', '29'=>'29', '30'=>'30', '31'=>'31', '32'=>'32', }, ), "\n
", checkbox(-Name=>'Parrot', -value=>'yes', -label=>$corpus->translate(' Parrot') ), "\n
", radio_group(-name=>'CompressionStyle', -Values=>[keys(%$refCompressionLablels)], -Labels=>$refCompressionLablels, -Linebreak=>'yes' ), "\n", textfield(-name=>'Tempo', -size=>length(param(-Name=>'Tempo')), -maxlength=>5 ), "\n
M", "\n", $corpus->translate('Selection'), "\n", $corpus->translate('Maximum'), "\n", $corpus->translate('Opposite'), "\n", $corpus->translate('Leg.'), "\n", $corpus->translate('Instrument'), "\n", $corpus->translate('Volume'), "\n
1", "\n",checkbox(-Name=>'Right Hand', -value=>'R', -label=>$corpus->translate('Right Hand') ), "\n",popup_menu(-name=>'RuleR', -Values=>['R 0', 'R 1', 'R 2', 'R 3', 'R 4', 'R 5', 'R 6', 'R 7', 'R 8', 'R 9', 'R 10', 'R 11', 'R 12', 'R 13', 'R 14', 'R 15', 'R 16' ], -Labels=>{'R 0'=>$corpus->translate('None'), 'R 1'=>'1', 'R 2'=>'2', 'R 3'=>'3', 'R 4'=>'4', 'R 5'=>'5', 'R 6'=>'6', 'R 7'=>'7', 'R 8'=>'8', 'R 9'=>'9', 'R 10'=>'10', 'R 11'=>'11', 'R 12'=>'12', 'R 13'=>'13', 'R 14'=>'14', 'R 15'=>'15', 'R 16'=>'16' }, ), "",popup_menu(-name=>'OppositeR', -Values=>['R R','R L','R O','R H','R S'], -labels=>{'R R'=>$corpus->translate('Right Hand'), 'R L'=>$corpus->translate('Left Hand'), 'R O'=>$corpus->translate('Bass Drum'), 'R H'=>$corpus->translate('Hit Hat'), 'R S'=>$corpus->translate('Silence') } ), "", "R", "", popup_menu_instrument('InstrR'), "", textfield(-name=>'VolR', -size=>length(param(-Name=>'VolR')), -maxlength=>5 ), "
2", "",checkbox(-Name=>'Left Hand', -value=>'L', -label=>$corpus->translate('Left Hand')), "",popup_menu(-name=>'RuleL', -Values=>['L 0', 'L 1', 'L 2', 'L 3', 'L 4', 'L 5', 'L 6', 'L 7', 'L 8', 'L 9', 'L 10', 'L 11', 'L 12', 'L 13', 'L 14', 'L 15', 'L 16' ], -Labels=>{'L 0'=>$corpus->translate('None'), 'L 1'=>'1', 'L 2'=>'2', 'L 3'=>'3', 'L 4'=>'4', 'L 5'=>'5', 'L 6'=>'6', 'L 7'=>'7', 'L 8'=>'8', 'L 9'=>'9', 'L 10'=>'10', 'L 11'=>'11', 'L 12'=>'12', 'L 13'=>'13', 'L 14'=>'14', 'L 15'=>'15', 'L 16'=>'16' }, ), "",popup_menu(-name=>'OppositeL', -Values=>['L R','L L','L O','L H','L S'], -labels=>{'L R'=>$corpus->translate('Right Hand'), 'L L'=>$corpus->translate('Left Hand'), 'L O'=>$corpus->translate('Bass Drum'), 'L H'=>$corpus->translate('Hit Hat'), 'L S'=>$corpus->translate('Silence') } ), "", "L", "", popup_menu_instrument('InstrL'), "", textfield(-name=>'VolL', -size=>length(param(-Name=>'VolL')), -maxlength=>5 ), "
3", "",checkbox(-Name=>'Bass Drum', -value=>'O', -label=>$corpus->translate('Bass Drum') ), "",popup_menu(-name=>'RuleO', -Values=>['O 0', 'O 1', 'O 2', 'O 3', 'O 4', 'O 5', 'O 6', 'O 7', 'O 8', 'O 9', 'O 10', 'O 11', 'O 12', 'O 13', 'O 14', 'O 15', 'O 16' ], -Labels=>{'O 0'=>$corpus->translate('None'), 'O 1'=>'1', 'O 2'=>'2', 'O 3'=>'3', 'O 4'=>'4', 'O 5'=>'5', 'O 6'=>'6', 'O 7'=>'7', 'O 8'=>'8', 'O 9'=>'9', 'O 10'=>'10', 'O 11'=>'11', 'O 12'=>'12', 'O 13'=>'13', 'O 14'=>'14', 'O 15'=>'15', 'O 16'=>'16' }, ), "",popup_menu(-name=>'OppositeO', -Values=>['O R','O L','O O','O H','O S'], -labels=>{'O R'=>$corpus->translate('Right Hand'), 'O L'=>$corpus->translate('Left Hand'), 'O O'=>$corpus->translate('Bass Drum'), 'O H'=>$corpus->translate('Hit Hat'), 'O S'=>$corpus->translate('Silence') } ), "", "O", "", popup_menu_instrument('InstrO'), "", textfield(-name=>'VolO', -size=>length(param(-Name=>'VolO')), -maxlength=>5 ), "
4", "",checkbox(-Name=>'Hit Hat', -value=>'H', -label=>$corpus->translate('Hit Hat') ), "",popup_menu(-name=>'RuleH', -Values=>['H 0', 'H 1', 'H 2', 'H 3', 'H 4', 'H 5', 'H 6', 'H 7', 'H 8', 'H 9', 'H 10', 'H 11', 'H 12', 'H 13', 'H 14', 'H 15', 'H 16' ], -Labels=>{'H 0'=>$corpus->translate('None'), 'H 1'=>'1', 'H 2'=>'2', 'H 3'=>'3', 'H 4'=>'4', 'H 5'=>'5', 'H 6'=>'6', 'H 7'=>'7', 'H 8'=>'8', 'H 9'=>'9', 'H 10'=>'10', 'H 11'=>'11', 'H 12'=>'12', 'H 13'=>'13', 'H 14'=>'14', 'H 15'=>'15', 'H 16'=>'16' }, ), "",popup_menu(-name=>'OppositeH', -Values=>['H R','H L','H O','H H','H S'], -labels=>{'H R'=>$corpus->translate('Right Hand'), 'H L'=>$corpus->translate('Left Hand'), 'H O'=>$corpus->translate('Bass Drum'), 'H H'=>$corpus->translate('Hit Hat'), 'H S'=>$corpus->translate('Silence') } ), "", "H", "", popup_menu_instrument('InstrH'), "", textfield(-name=>'VolH', -size=>length(param(-Name=>'VolH')), -maxlength=>5 ), "
5", "",checkbox(-Name=>'Silence', -value=>'S', -label=>$corpus->translate('Silence') ), "",popup_menu(-name=>'RuleS', -Values=>['S 0', 'S 1', 'S 2', 'S 3', 'S 4', 'S 5', 'S 6', 'S 7', 'S 8', 'S 9', 'S 10', 'S 11', 'S 12', 'S 13', 'S 14', 'S 15', 'S 16' ], -Labels=>{'S 0'=>$corpus->translate('None'), 'S 1'=>'1', 'S 2'=>'2', 'S 3'=>'3', 'S 4'=>'4', 'S 5'=>'5', 'S 6'=>'6', 'S 7'=>'7', 'S 8'=>'8', 'S 9'=>'9', 'S 10'=>'10', 'S 11'=>'11', 'S 12'=>'12', 'S 13'=>'13', 'S 14'=>'14', 'S 15'=>'15', 'S 16'=>'16' }, ), "",popup_menu(-name=>'OppositeS', -Values=>['S R','S L','S O','S H','S S'], -labels=>{'S R'=>$corpus->translate('Right Hand'), 'S L'=>$corpus->translate('Left Hand'), 'S O'=>$corpus->translate('Bass Drum'), 'S H'=>$corpus->translate('Hit Hat'), 'S S'=>$corpus->translate('Silence') } ), "", "S", "", "", "
6", "", checkbox( -Name=>'Click', -value=>'K', -label=>$corpus->translate('Click') ), "", $corpus->translate('Where'), " : ", textfield(-name=>'ClickTimes', -maxlength=>50 ), "", popup_menu_instrument('InstrK'), "", textfield(-name=>'VolK', -size=>length(param(-Name=>'VolK')), -maxlength=>5 ), "
","
", "
", "\n", endform, "\n"; #print dump,"\n"; &makeHashes("Right Hand"); &makeHashes("Left Hand"); &makeHashes("Bass Drum"); &makeHashes("Hit Hat"); &makeHashes("Silence"); #if (open (OUT,">memo.param")) { # $query->save(OUT); # close (OUT); #} @estimateResult = estimateNumberOfSequences(16,0,values(%Rule)); $lengthOfSequences = param(Length); @estimateOutputLengthCaracter = estimateOutputLength(" caracter",@estimateResult); @estimateOutputLengthScore = estimateOutputLength(" score",@estimateResult); @clickTime = split (/\s+/, param(-Name=>'ClickTimes')); $doParrot = (defined (param(-Name=>'Parrot')) and (param(-Name=>'Parrot') eq 'yes')) ? "1" : "0"; $clickCount = 0; foreach $clickTime (@clickTime) { if ($clickTime =~ /\A\d+\Z/) { $clickTime{$clickTime} = 1 ; #print "clickTime: $clickTime
\n"; if (($clickTime <= $lengthOfSequences) and ($clickTime >= 1)) { $clickCount++; } } } #print "clickCount: $clickCount
\n"; @estimateMidiOutputLength = estimateMidiOutputLength(param(-Name=>'Repeat'), @estimateResult); $maxNumberOfSequences = supBorderOf($confParameters{"PatternNumberMax"}, @estimateResult); $maxlengthOfSequencesInCaracter = supBorderOf($confParameters{"ResultLengthMax"}, @estimateOutputLengthCaracter); $maxlengthOfSequencesInScore = supBorderOf($confParameters{"ResultLengthMax"}, @estimateOutputLengthScore); $maxlengthMidiFile = supBorderOf($confParameters{"ResultMidiLengthMax"}, @estimateMidiOutputLength); # Looking for the length limit in each case (Number Of sequences, # lengthOfSequencesInCaracter, lengthOfSequencesInScore $lengthLimitBySequences = 16+1; $lengthLimitByCaracter = 16+1; $lengthLimitByScore = 16+1; $lengthLimitByMidi = 16+1; foreach $num (reverse(1..16)){ $lengthLimitBySequences = $num if ($maxNumberOfSequences < $estimateResult[$num-1]); $lengthLimitByCaracter = $num if ($maxlengthOfSequencesInCaracter < $estimateOutputLengthCaracter[$num - 1]); $lengthLimitByScore = $num if ($maxlengthOfSequencesInScore < $estimateOutputLengthScore[$num - 1]); $lengthLimitByMidi = $num if ($maxlengthMidiFile < $estimateMidiOutputLength[$num - 1]); } print "\n
\n", "\n", "", "", "", "", "
",$corpus->translate('Estimations'),"\n", "
",$corpus->translate('Length'),"\n"; $AbsolutLimit = min( $lengthLimitBySequences, max_liste($lengthLimitByCaracter, $lengthLimitByScore, $lengthLimitByMidi) ); foreach $num (1..16){ print "\n"; if ($num < $AbsolutLimit ) { # Allowed demand # A good one if ($num eq $lengthOfSequences) { print "$num\n"; }else { # The last choosen, for better reading. print "$num\n"; } }else { # Forbidden ! if ($num eq $lengthOfSequences) { print "$num\n"; }else { print "$num\n"; } } } print "\n
",$corpus->translate('Sequences'), "\n"; foreach $num (1..16){ print "\n"; if ($num < $AbsolutLimit) { # Allowed demand # A good one if ($num eq $lengthOfSequences) { print "$estimateResult[$num -1]\n"; }else { # The last choosen, for better reading. print "$estimateResult[$num -1]\n"; } }else { # Forbidden ! if ($num eq $lengthOfSequences) { print "", "$estimateResult[$num -1]\n"; }else { print "$estimateResult[$num -1]\n"; } } } print "\n
",$corpus->translate('Html weight Letter (Ko)'), "\n"; foreach $num (1..16){ print "\n"; if ($num < min($lengthLimitBySequences,$lengthLimitByCaracter)) { # Allowed demand # A good one if ($num eq $lengthOfSequences) { if (defined(param(-Name=>'Graphics')) and param(-Name=>'Graphics') and param(OutputStyle) eq " caracter"){ print "\n", "$estimateOutputLengthCaracter[$num - 1]\n"; }else{ print "$estimateOutputLengthCaracter[$num - 1]\n"; } }else { # The last choosen, for better reading. print "$estimateOutputLengthCaracter[$num - 1]\n"; } }else { # Forbidden ! if ($num eq $lengthOfSequences) { if (defined(param(-Name=>'Graphics')) and param(-Name=>'Graphics') and param(OutputStyle) eq " caracter"){ print "\n", "$estimateOutputLengthCaracter[$num - 1]\n"; }else{ print "$estimateOutputLengthCaracter[$num - 1]\n"; } }else{ print "\n", "$estimateOutputLengthCaracter[$num - 1]\n", "\n"; } } } print "\n
",$corpus->translate('Html weight Score (Ko)'), "\n"; foreach $num (1..16){ print "\n"; if ($num < min($lengthLimitBySequences,$lengthLimitByScore)) { # Allowed demand # A good one if ($num eq $lengthOfSequences) { if (defined(param(-Name=>'Graphics')) and param(-Name=>'Graphics') and param(OutputStyle) eq " score"){ print "\n", "$estimateOutputLengthScore[$num - 1]\n", "\n"; }else{ print "$estimateOutputLengthScore[$num - 1]\n"; } }else { print "$estimateOutputLengthScore[$num - 1]\n"; } }else { # Forbidden ! if ($num eq $lengthOfSequences) { if (defined(param(-Name=>'Graphics')) and param(-Name=>'Graphics') and param(OutputStyle) eq " score"){ print "\n", "$estimateOutputLengthScore[$num - 1]\n", ""; }else{ print "$estimateOutputLengthScore[$num - 1]\n"; } }else{ print "$estimateOutputLengthScore[$num - 1]\n"; } } } print "\n
",$corpus->translate('Midi weight file (Ko)'), "\n"; foreach $num (1..16){ print "\n"; if ($num < min($lengthLimitBySequences,$lengthLimitByMidi)) { # Allowed demand # A good one if ($num eq $lengthOfSequences) { if (defined(param(-Name=>'Midi')) and param(-Name=>'Midi') eq 'yes'){ print "\n", "$estimateMidiOutputLength[$num - 1]\n", "\n"; }else{ print "$estimateMidiOutputLength[$num - 1]\n"; } }else { print "$estimateMidiOutputLength[$num - 1]\n"; } }else { # Forbidden ! if ($num eq $lengthOfSequences) { if (param(-Name=>'Midi') eq 'yes'){ print "\n", "$estimateMidiOutputLength[$num - 1]\n", ""; }else{ print "$estimateMidiOutputLength[$num - 1]\n"; } }else{ print "$estimateMidiOutputLength[$num - 1]\n"; } } } print "
", "

\n"; # Now, do we go to computation ? if (param(-Name=>'Graphics')) { if (param(OutputStyle) eq " score") { if ($lengthOfSequences >= $lengthLimitByScore) { $NoOutput{'score'} = 1; #print "NoScoreOutput
\n"; }else{ $doComputation++; #print $doComputation, " score
\n"; } } if (param(OutputStyle) eq " caracter") { if ($lengthOfSequences >= $lengthLimitByCaracter) { $NoOutput{'caracter'} = 1; #print "NoScoreOutput
\n"; }else{ $doComputation++; #print $doComputation, " caracter
\n"; } } } if (param(-Name=>'Midi')) { if ($lengthOfSequences >= $lengthLimitByMidi) { $NoOutput{'midi'} = 1; #print "NoMidiOutput
\n"; }else{ $doComputation++; #print $doComputation, " midi
\n"; } } foreach (qw(score caracter midi)){ if (defined($NoOutput{$_})){ print "
\n", "", $corpus->translate("Output"), " ", $corpus->translate($_), " ", $corpus->translate("not allowed"), "
\n", "
", "
\n" ; $seeTable++; } } if (defined($seeTable)) { print "
\n", "", $corpus->translate('See the "Estimations" table below.'), "", "
\n", "
\n"; } unless (defined($doComputation)) { print end_html,"\n"; exit; } local (%Count); %Count = %Rule; # Write the tr parameters $trListe = &computeTrListe(); # Compute all the combinaisons with rules $SIG{ALRM} = sub { die "Too slow"; }; eval { alarm($confParameters{"TimeOutCalcul"}); @result = allnew (${lengthOfSequences},\%Rule,\%Count); # Prepare a good hash for better filtering, output sorting, midi $countCombin = 0; if (${lengthOfSequences} != length($result[0])) { @result = (); }else{ foreach $combin (@result) { ++$countCombin; if (loopable($combin)){ $combin{$countCombin}{'loopable'} = 1; } if ( invertable($combin)){ $combin{$countCombin}{'invertable'} = 1; } $combin{$countCombin}{'normal'} = $combin; $combin{$countCombin}{'invert'} = invert($combin); } } $sequencesNumberComp = scalar(@result); $numDigit = length(2*scalar(@result)); # making the midi stuff midistuff() if (param(-Name=>'Midi') and not defined($NoOutput{'midi'})); # Make a good output of the result if (param(-Name=>'Graphics')){ SWITCH: { param(OutputStyle) eq " score" and not defined($NoOutput{'score'}) and &resultForOutputScore("score_small_format"),last SWITCH; param(OutputStyle) eq " caracter" and not defined($NoOutput{'caracter'}) and &resultForOutputCaracter(),last SWITCH; } } alarm(0); }; if ($@ =~ /Too slow/) { print "


\n", $corpus->translate('I could not finish the filtering computation.'), " ", $corpus->translate('The WebMaster told me to spend only'), " ", $confParameters{"TimeOutCalcul"}, " ", $corpus->translate('secondes for you.'), "

\n"; } $lengthInKo = int(length(join("",@outputString))/1024)+1; # Display loopable and invertable combinaisons print ("
\n","

\n"); displayPatterns(); print ("
\n","

\n"); $globalEnd = new Benchmark; $globalDiff = timediff($globalEnd,$globalBegin); if ($sequencesNumberComp == 0) { $filterPerCent = 0; }else{ $sequencesNumberOut = (defined($sequencesNumberOut)) ? $sequencesNumberOut : 0; $filterPerCent = sprintf "%2.2f", 100*(1-(($sequencesNumberOut)/(2*$sequencesNumberComp))); } $runningTimeStr = timestr($globalDiff); $runningTimeStr =~ /\A.*\s+(\d+\.\d+)\s*cpu\s*\).*\Z/; $runningTime = $1; print "

\n", "\n", "", "", "\n", "", "\n", "
\n", $corpus->translate('Results'), "\n", "
",$corpus->translate('Running Time'), "\n", "",$corpus->translate('Computed sequences'), "\n", "",$corpus->translate('Printed sequences'), "\n", "",$corpus->translate('Filtering'), "\n", "",$corpus->translate('Html weight'), "\n", "
", $runningTime, " secs", "\n", "", "\n", "",$sequencesNumberComp * 2, "", "\n", "", "\n", "",$sequencesNumberOut, "", "\n", "", "\n", "", $filterPerCent, " %", "", "\n", "", "\n", "",$lengthInKo, " Ko", "", "\n", "

\n" ; print end_html, "\n"; ############################################################################### sub makeHashes { local($titleMember) = (@_); if (param(-Name=>$titleMember)){ $nameMember = param(-Name=>$titleMember); #print "$nameMember :
\n"; @listeCouple = split(" ",param("Rule${nameMember}")); $nameMember = shift @listeCouple; $numberRule = pop @listeCouple; #print "$nameMember : $numberRule
\n"; @listeCouple = split(" ",param("Opposite${nameMember}")); $oppositeMember = pop @listeCouple; $Rule{$nameMember} = $numberRule; $Opposite{$nameMember} = $oppositeMember; @listeCouple = split(" ",param("Rule${oppositeMember}")); #print "\n",h3(@listeCouple); $ruleOppositeMember = pop(@listeCouple); #print "\n",h3("Rule${oppositeMember}:",$ruleOppositeMember); $RuleOpposite{$oppositeMember} = $ruleOppositeMember; } } ############################################################################### sub resultForOutputCaracter { my ($countLine) = (0); @outputString = (); ${countLine} = sprintf "%${numDigit}.${numDigit}d", ++${countLine}; #this awful code is needed for a good output text # push @outputString , ("\n\n", " " x (2*${lengthOfSequences}-4), "looping with ...
\n", "_" x (4*${lengthOfSequences}+7+2*${numDigit}),"
\n", " " x (${lengthOfSequences}-2+((${numDigit}+2)/2)), "itself", " " x (${lengthOfSequences}-2+((${numDigit}+1)/2)), "|", " " x (${lengthOfSequences}-2+((${numDigit}+1)/2)), "invert", " "x (${lengthOfSequences}-2+((${numDigit}+1)/2)), "

\n"); # $begin = new Benchmark; foreach $combin (@result) { if ( loopable($combin)){ push @outputString ,("$countLine ${combin} ${combin} | "); }else{ push @outputString ,("$countLine ${combin} ${combin} | "); } ${countLine} = sprintf "%${numDigit}.${numDigit}d", ++${countLine}; $sequencesNumberOut++; $invertCombin = invert($combin) ; unless ( $invertCombin eq $combin) { if ( invertable($combin)){ push @outputString, ("$countLine ${combin}" ," " , $invertCombin .""); }else{ push @outputString,("$countLine ${combin}" , " " , $invertCombin); } ${countLine} = sprintf "%${numDigit}.${numDigit}d", ++${countLine}; $sequencesNumberOut++; }else{ push @outputString, ("$countLine ", "-" x (2*${lengthOfSequences}+1)); ${countLine} = sprintf "%${numDigit}.${numDigit}d", ++${countLine}; } push @outputString, ("
\n"); } push @outputString, ("
\n"); } ################################################################################ sub resultForOutputScore { ($imageType) = (@_); my ($countLine,$stringImage,$stringImageDeb,$stringImageMid, $stringImageFin,$stringImageInverted,$invertCombin) = (0); SWITCH : { $imageType eq "score_small_format" and %images = ( L => 'L', R => 'R', H => 'H', O => 'O', S => 'S', D => 'D', M => 'M', F => 'F' ) , last SWITCH; } @outputString = (); ${countLine} = sprintf "%${numDigit}.${numDigit}d", ++${countLine}; foreach $combin (@result) { $atLeastOne = 0; $invertCombin = &invert($combin) ; $lineBreak = (${lengthOfSequences} > $lineBreakLimit) ? "
\n": ""; $stringImageDeb = &formatedString("D"); $stringImageMid = &formatedString("M"); $stringImageFin = &formatedString("F"); $stringImage = &formatedString($combin); $stringImageInverted = &formatedString($invertCombin); if ( &loopable($combin)){ # a good combinaison (respect the rules) push @outputString, ( "${countLine}", "$stringImageDeb", "$stringImage", "$stringImageMid", "$stringImage", "$stringImageFin" ); $atLeastOne++; $sequencesNumberOut++; }else{ # a bad combinaison (do not respect the rules) unless ($doFilter eq 'yes') { push @outputString, ( "${countLine}", "$stringImageDeb", "$stringImage", "$stringImageMid", "$stringImage", "$stringImageFin" ); $atLeastOne++; $sequencesNumberOut++; }else { # nothing to print } } ${countLine} = sprintf "%${numDigit}.${numDigit}d", ++${countLine}; unless ( $invertCombin eq $combin) { if ( &invertable($combin)){ # a good combinaison (respect the rules) push @outputString, ("${lineBreak}") if ($atLeastOne); push @outputString, ( "${countLine}", "$stringImageDeb", "$stringImage", "$stringImageMid", "$stringImageInverted", "$stringImageFin", ); $atLeastOne++; $sequencesNumberOut++; }else{ # a bad combinaison (do not respect the rules) unless ($doFilter eq 'yes') { push @outputString, ("${lineBreak}") if ($atLeastOne); push @outputString, ( "${countLine}", "$stringImageDeb", "$stringImage", "$stringImageMid", "$stringImageInverted", "$stringImageFin" ); $atLeastOne++; $sequencesNumberOut++; }else { # nothing } } }else{ # the same string -> nothing to do } ${countLine} = sprintf "%${numDigit}.${numDigit}d", ++${countLine}; push @outputString, ("
\n") if ($atLeastOne); } } ############################################################################### sub readTheConfigurationFile { my(%paramConf); my($configurationFile) = @_; #default values %paramConf = ( "PatternNumberMax" => "unlimited", "ResultLengthMax" => "500", "ResultMidiLengthMax" => "500", "TimeOutCalcul" => "0", 'WorldWritableDirectory' => '../WWR', 'maxSizeWorldWritableDirectory' => '500', 'tclInterpreter' => '/usr/bin/tcl' ); open(CONF,$configurationFile) or die "Can not open $configurationFile : $!"; while () { next if /^#/; next if /^\s*$/; if (/^[ \t]*(\w+)[ \t]+(.+)$/){ $arg2=$2; $arg1=$1; $arg2 =~ s/\A(.*?)\s*\Z/$1/; #warn "arg2=$arg2\n"; $paramConf{$arg1}=$arg2; } else { die "Syntax error in the configuration File : $configurationFile", " line $INPUT_LINE_NUMBER\n", "You have to use only alphanumeric terms\n", "A correct syntax example :\n", " ResultLengthMax 500 \n"; } } close(CONF); return %paramConf; } ################################################################################ sub supBorderOf{ my ($border,@listOfNumber) = @_; my ($result); #print "Border : $border : @listOfNumber
\n"; $result = 0; foreach $number (@listOfNumber){ if (($result <= $number) and (("$border" eq "unlimited") or ($border >= $number))){ $result = $number; } } return $result; } ################################################################################ sub formatedString { my ($inString) = (@_); my ($outString) = (""); @inString = split(//,$inString); foreach $char (@inString) { $outString .= ""; } return $outString; } ################################################################################ sub displayPatterns { print "
", @outputString, "
"; } ################################################################################ sub loopable { local($combin) = (@_); local($first,$howManyOfFirst,$lastC,$howManyOfLast); # first character ? $first = substr($combin, 0, 1); # last character ? $lastC = substr($combin, -1, 1); if (${lastC} eq ${first}) { # number of identical characters $combin =~ m/^(${first}+).*?(${lastC}+)$/; $howManyOfFirst = length($1); $howManyOfLast = length($2); #print "first=$first $howManyOfFirst, last=${lastC} $howManyOfLast "; unless ( ${howManyOfFirst} + ${howManyOfLast} > $Rule{${first}} ) { if (${howManyOfFirst} + ${howManyOfLast} == length($combin)){ return 0; } else { return "true"; } }else { return 0; } }else { return "true"; } } ################################################################################ sub invertable { local($combin) = (@_); local($invertCombin, $concatCombin); $invertCombin = &invert($combin); $concatCombin = $combin . $invertCombin ; # looking if there are too much caracters foreach $caracter (keys %RuleOpposite) { $numberOfCaracterToMatch = $RuleOpposite{$caracter}+1; if ($concatCombin =~ m/(${caracter}{$numberOfCaracterToMatch,})/) {return 0} } $concatCombin = $invertCombin . $combin ; # looking again if there are too much caracters (reverse order) foreach $caracter (keys %RuleOpposite) { $numberOfCaracterToMatch = $RuleOpposite{$caracter}+1; if ($concatCombin =~ m/(${caracter}{$numberOfCaracterToMatch,})/) {return 0} } return "true"; } ################################################################################ sub computeTrListe { $replaceListe = ""; $searchListe = ""; foreach $caracter (keys %Rule) { $searchListe .= $caracter; $replaceListe .= $Opposite{$caracter}; } $trListe = "${searchListe}/${replaceListe}"; if (${trListe} =~ /\A(.*)\Z/) { ${trListe} = $1; return ${trListe}; }else{ return undef; }; } ################################################################################ sub invert { ($_) = @_; eval "tr/${trListe}/"; return $_; } ################################################################################ sub min { local($N,$S) = @_; if ( $S >= $N) { return ($N); }else{ return ($S); } } ################################################################################ sub max_liste { my $max = shift(@_); foreach $foo (@_) { $max = $foo if $max < $foo; } return $max; } ################################################################################ sub clearThis { my @cleared = (); foreach $value (@_) { push (@cleared, $value) if defined ($value); } return @cleared; } ################################################################################ sub estimateNumberOfSequences { # 1er élément : Longueur du mot dont on veut obtenir toutes les combinaisons # # reste : vecteur représentant le nombre maximal de coups consécutifs # pour chaque membre local($lenght_word, @m) = @_; local($m_max, $m_dim, @list_result); # Création de matrices : max(@m) matrices binaires de dimension # (t(@m)-1)x(t(@m)-1), max(@m) étant le plus grand nombre du vecteur # @m et t(@m) la taille du vecteur @m. $m_max = max_liste(@m); $m_dim = @m -1; #print "m_max = $m_max\n"; #print "m_dim = $m_dim\n"; # Les diagonales sont à zéro et le reste dépend des règles. on a : # # 0 a(R,1) a(R,1) a(R,1) 0 a(R,2) a(R,2) a(R,2) ... # a(L,1) 0 a(L,1) a(L,1) a(L,2) 0 a(L,2) a(L,2) ... # a(O,1) a(O,1) 0 a(O,1) a(O,2) a(O,2) 0 a(O,2) ... # a(X,1) a(X,1) a(X,1) 0 a(X,2) a(X,2) a(X,2) 0 ... # # avec a(R,i) = 1 si un nombre i de R consécutifs sont autorisés et # = 0 dans le cas contraire for $mat (1 .. $m_max) { for $ligne (1 .. $m_dim) { for $colomn (1 ..$m_dim) { if (($m[$ligne] >= $mat) and ($ligne != $colomn)) { $ensMatAlpha[$mat][$ligne][$colomn] = 1; }else{ $ensMatAlpha[$mat][$ligne][$colomn] = 0; } } } } # Une matrice $m_max x t(@m) representant les # # fR(n-1), fR(n-2), ... , fR(n-k) # fL(n-1), fL(n-2), ... , fL(n-k) # fO(n-1), fO(n-2), ... , fO(n-k) # fX(n-1), fX(n-2), ... , fX(n-k) # somme , somme , ... , somme # # où somme est la somme des eléments de la colomne situés au-dessus for $N (1 .. $m_max) { for $ligne (1 .. ($m_dim + 1)) { $f[$ligne][$N] = 0; } } # Une matrice $m_dim x $m_max pour la génération des premiers termes # multiples (RR RRR RRRR ...) for $ligne (1 .. $m_dim){ for $N (1 .. $lenght_word) { if ($m[$ligne] >= $N) { $init[$ligne][$N] = 1 ; }else{ $init[$ligne][$N] = 0; } } } @list_result = (); foreach $count (1 .. $lenght_word){ for $ligne (1 .. $m_dim) { $somColm = 0; for $N (1 .. $m_max) { for $colomn (1 .. $m_dim) { $somColm= ($somColm + ($ensMatAlpha[$N][$ligne][$colomn] * $f[$colomn][$N])); } } $Result[$ligne] = $somColm + $init[$ligne][$count]; } # rotation des fR(n-1) fR(n-2), ... , fR(0) # fL(n-1) fL(n-2), ... , fL(0) # fO(n-1) fO(n-2), ... , fO(0) # fX(n-1) fX(n-2), ... , fX(0) # S(n-1) S(n-2), ... , S(0) foreach $N (reverse 2 .. $m_max) { for $ligne (1 .. ($m_dim + 1)) { $f[$ligne][$N] = $f[$ligne][$N-1]; } } $f[$m_dim +1][1] = 0; for $ligne (1 .. $m_dim) { $f[$ligne][1] = $Result[$ligne]; $f[$m_dim + 1][1] += $Result[$ligne]; # La somme } push(@list_result , $f[$m_dim +1][1]); #&print_result; } #print "@list_result\n"; return(@list_result); } ################################################################################ sub estimateOutputLength { local($outputStyle,@estimateResult) = @_; local(@estimateOutputLength) = (); local($numDigit); if ($outputStyle eq " caracter") { foreach $num (1..16){ $numDigit = length(2 * scalar($estimateResult[$num - 1])); $ligneLength =(3 + $numDigit + 2 + $num * 2 + 10 + $numDigit + 2 + $num * 2 + 9); #$totalLength = $estimateResult[ $num - 1]*$ligneLength; $totalLength = int(($estimateResult[${num}-1]*$ligneLength)/1024)+1; push (@estimateOutputLength,"$totalLength"); } }else{ $lengthImageCode = length(""); foreach $num (1..16) { $numDigit = length(2 * scalar($estimateResult[$num -1])); $ligneLength =(3 + $numDigit + $lengthImageCode * ($num * 2 +3) + 7 + $numDigit + $lengthImageCode * ($num * 2 +3) + 9); #$totalLength = $estimateResult[${num}-1]*$ligneLength; $totalLength = int(($estimateResult[$num -1]*$ligneLength)/1024)+1; push (@estimateOutputLength,"$totalLength"); } } return (@estimateOutputLength); } ################################################################################ sub estimateMidiOutputLength { my($repeat, @estimateResult) = @_; my(@estimateOutputLength) = (); foreach $num (1..16){ my($totalLength); $totalLength = int(((182+ ($estimateResult[${num}-1] * $repeat * ((24 * $clickCount * (1 + $doParrot)) + (32 * $num))))/1024)+0.5); push (@estimateOutputLength,$totalLength); } return (@estimateOutputLength); } ################################################################################ sub allnew { local ($N, *refRule, *refCount) = @_; local (@list) = (); local $keyListPatternsAlreadyCalculated ; # For beginning, the end of recursion if ($N eq 0 ) { return (); }else{ # Ok, let us go for the multiple recursion, note the label "KEY" at the # beginning of the next line KEY:foreach $key (keys %refRule) { # /* !!! THE MOST IMPORTANT LIGNE OF THIS CODE !!!*/ local (%Count)= %refCount; if ($Count{$key} eq 0) { # the counter is empty, reinit of the counter, nothing to search $Count{$key} = $refRule{$key} ; next KEY; } else { foreach $keyLocal (keys %refRule) { unless ( $keyLocal eq $key) { # other member counters are reinitiated $Count{$keyLocal} = $refRule{$keyLocal}; } } $Count{$key} -= 1; # This misterious AlreadyCalculated code is only here # to divide the running time by 2, and to make # this code very very ugly. $keyListPatternsAlreadyCalculated = $N - 1 . "*"; while (($keyOfCount,$ValueOfCount) = each %Count) { $keyListPatternsAlreadyCalculated .= "${keyOfCount}". &min($N - 1,${ValueOfCount}); } if (defined( $listPatternsAlreadyCalculated{${keyListPatternsAlreadyCalculated}} ) ) { #print "DEF-
\n"; @subList = @{ $listPatternsAlreadyCalculated{${keyListPatternsAlreadyCalculated}} }; }else { @subList = allnew($N - 1,\%refRule,\%Count); $listPatternsAlreadyCalculated{${keyListPatternsAlreadyCalculated}} = [@subList]; # It is sometimes very very hard to debug recurcive code. # The better thing I found : #print "MEM-"; #print "${keyListPatternsAlreadyCalculated}
\n"; #print "----",$N - 1, "_"; #print %Count; #print "
\n"; #@temp = @subList; #foreach $combinTemp (@temp){ # print $combinTemp ; # print "
\n"; #} } do{ if (@subList > 0){ push @list, ("$key" . shift(@subList)); }else { push @list, ("$key"); } }while @subList; } } return @list; } } sub popup_menu_instrument { return( popup_menu(-name=>@_, -Values=>[ '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', ], -labels=>{ '35' => $corpus->translate('Acoustick Kick'), '36' => $corpus->translate('Rock Kick'), '37' => $corpus->translate('Side Stick'), '38' => $corpus->translate('Acoustic Snare'), '39' => $corpus->translate('HandClap'), '40' => $corpus->translate('Electric Snare'), '41' => $corpus->translate('Low Floor Tom'), '42' => $corpus->translate('Closed Hi-Hat'), '43' => $corpus->translate('High Floor Tom'), '44' => $corpus->translate('Pedal Hi-Hat'), '45' => $corpus->translate('Low Tom'), '46' => $corpus->translate('Open Hi-Hat'), '47' => $corpus->translate('Low Mid-Tom'), '48' => $corpus->translate('High Mid-Tom'), '49' => $corpus->translate('Crash Cymbal 1'), '50' => $corpus->translate('High Tom'), '51' => $corpus->translate('Ride Cymbal 1'), '52' => $corpus->translate('Chinese Cymbal'), '53' => $corpus->translate('Ride Bell'), '54' => $corpus->translate('Tambourine'), '55' => $corpus->translate('Splash Cymbal'), '56' => $corpus->translate('Cowbell'), '57' => $corpus->translate('Crash Cymbal 2'), '58' => $corpus->translate('Vibraslap'), '59' => $corpus->translate('Ride Cymbal 2'), '60' => $corpus->translate('High Bongo'), '61' => $corpus->translate('Low Bongo'), '62' => $corpus->translate('Mute High Conga'), '63' => $corpus->translate('Open High Conga'), '64' => $corpus->translate('Low Conga'), '65' => $corpus->translate('High Timbale'), '66' => $corpus->translate('Low Timbale'), '67' => $corpus->translate('High Agogo'), '68' => $corpus->translate('Low Agogo'), '69' => $corpus->translate('Cabasa'), '70' => $corpus->translate('Maracas'), '71' => $corpus->translate('Short Whistle'), '72' => $corpus->translate('Long Whistle'), '73' => $corpus->translate('Short Guiro'), '74' => $corpus->translate('Long Guiro'), '75' => $corpus->translate('Claves'), '76' => $corpus->translate('High Woodblock'), '77' => $corpus->translate('Low Woodblock'), '78' => $corpus->translate('Mute Cuica'), '79' => $corpus->translate('Open Cuica'), '80' => $corpus->translate('Mute Triangle'), '81' => $corpus->translate('Open Triangle') } ) ) } sub dec2binf { ($numberOfBit, $numberToConvert) = @_ ; warn "bit number $numberOfBit is > 32: conversion may be wrong" if ($numberOfBit > 32); return "" if ($numberOfBit <= 0); return substr (unpack ("B32", pack("N", $numberToConvert)), -$numberOfBit); } sub convert64bin2alph { my(@bininput) = @_; my(%convert64, @result); %convert64 = ( "000000" => "0", "000001" => "1", "000010" => "2", "000011" => "3", "000100" => "4", "000101" => "5", "000110" => "6", "000111" => "7", "001000" => "8", "001001" => "9", "001010" => "a", "001011" => "b", "001100" => "c", "001101" => "d", "001110" => "e", "001111" => "f", "010000" => "g", "010001" => "h", "010010" => "i", "010011" => "j", "010100" => "k", "010101" => "L", "010110" => "m", "010111" => "n", "011000" => "o", "011001" => "p", "011010" => "q", "011011" => "r", "011100" => "s", "011101" => "t", "011110" => "u", "011111" => "v", "100000" => "w", "100001" => "x", "100010" => "y", "100011" => "z", "100100" => "A", "100101" => "B", "100110" => "C", "100111" => "D", "101000" => "E", "101001" => "F", "101010" => "G", "101011" => "H", "101100" => "I", "101101" => "J", "101110" => "K", "101111" => "L", "110000" => "M", "110001" => "N", "110010" => "O", "110011" => "P", "110100" => "Q", "110101" => "R", "110110" => "S", "110111" => "T", "111000" => "U", "111001" => "V", "111010" => "W", "111011" => "X", "111100" => "Y", "111101" => "Z", "111110" => "-", "111111" => "_", ); foreach $binvalue (@bininput) { my($conv, $mod, $lackzero); $conv=""; $mod = length($binvalue)%6 ; $lackzero = ((6 - $mod) == 6) ? 0 : 6 - $mod; $binvalue .= "0" x $lackzero; foreach (0 .. ((length($binvalue)/6)-1)){ my($extract); $extract = substr($binvalue, (6*$_), 6); $conv .= $convert64{$extract}; } push @result, $conv ; } return @result; } sub midistuff { my($division, $tempo, $instrR, $instrL, $instrO, $instrH, $instrK, $time); unless (-x $confParameters{'tclInterpreter'}){ print "
\n", "", $corpus->translate("Could not found the tcl interpreter"), "", "
\n", "
\n"; return; }; $division = 24; $division2 = 2*$division; $division3 = 3*$division; $division4 = 4*$division; $divisionLast = 8*$division; #$instr = instr; $tempo = param(-Name=>'Tempo'); $channel = 9; $instr{'R'} = param(-Name=>'InstrR'); $instr{'L'} = param(-Name=>'InstrL'); $instr{'H'} = param(-Name=>'InstrH'); $instr{'O'} = param(-Name=>'InstrO'); $instr{'K'} = param(-Name=>'InstrK'); $Vol{'R'} = param(-Name=>'VolR'); $Vol{'L'} = param(-Name=>'VolL'); $Vol{'H'} = param(-Name=>'VolH'); $Vol{'O'} = param(-Name=>'VolO'); $Vol{'K'} = param(-Name=>'VolK'); $wwd = $confParameters{'WorldWritableDirectory'}; $maxWWDsize = $confParameters{'maxSizeWorldWritableDirectory'} * 1024; # stop midi stuff if WWR directory is not writable unless ( -e $wwd and -d _ and -r _ and -w _){ print "Could not open ", $wwd, " in writable mode. ", "Please contact the WebMaster"; return; } if (opendir WWD, $wwd) { @midfiles = grep !/(^\.)|tmp/, readdir WWD; #print "@midfiles", ""; closedir WWD; foreach $file (@midfiles) { my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks); ($midfiles{"$wwd/$file"}{'size'}, $midfiles{"$wwd/$file"}{'atime'}) = (stat "$wwd/$file")[7, 8]; #print # "name: ", "$wwd/$file", "\n", # "size: ", $midfiles{"$wwd/$file"}{'size'}, "\n", # "atime: ", $midfiles{"$wwd/$file"}{'atime'}, "
\n"; } my($sizeSum); foreach $file (sort { $midfiles{$b}{'atime'} <=> $midfiles{$a}{'atime'} } keys(%midfiles)) { $confParameters{'debugMidi'} and print "$file : ", $midfiles{$file}{'atime'}, "
\n"; $sizeSum += $midfiles{$file}{'size'}; if ($sizeSum >= $maxWWDsize) { $midfiles{$file}{'delete'} = "yes"; $confParameters{'debugMidi'} and print "to delete: "; if (unlink($file)) { $confParameters{'debugMidi'} and print "deleted", "
\n"; }else{ print "could not $!", "
\n"; } }else{ $midfiles{$file}{'delete'} = "no"; $confParameters{'debugMidi'} and print "to keep", "
\n"; } $confParameters{'debugMidi'} and print "Sum: $sizeSum", "
\n"; } }else{ print "Could not open ", $wwd, ""; return; } # Here the stuff to construct the file name $binLengthOfSequences = dec2binf "5", $lengthOfSequences; #print "Length:[$binLengthOfSequences]"; $binFilter = dec2binf "1", ($doFilter eq 'yes') ? 1 : 0; #print "Filter:[$binFilter]"; $binRepeat = dec2binf "5", param(-Name=>'Repeat') - 1; $binParrot = dec2binf "1", (defined (param(-Name=>'Parrot')) and (param(-Name=>'Parrot') eq 'yes')) ? "1" : "0"; $binTempo = dec2binf "11", param(-Name=>'Tempo'); $binRightHand = dec2binf "1", (defined (param(-Name=>'Right Hand')) and (param(-Name=>'Right Hand') eq 'R')) ? "1" : "0"; $binLeftHand = dec2binf "1", (defined (param(-Name=>'Left Hand' )) and (param(-Name=>'Left Hand') eq 'L')) ? "1" : "0"; $binBassDrum = dec2binf "1", (defined (param(-Name=>'Bass Drum' )) and (param(-Name=>'Bass Drum') eq 'O')) ? "1" : "0"; $binHitHat = dec2binf "1", (defined (param(-Name=>'Hit Hat' )) and (param(-Name=>'Hit Hat') eq 'H')) ? "1" : "0"; $binSilence = dec2binf "1", (defined (param(-Name=>'Silence' )) and (param(-Name=>'Silence') eq 'S')) ? "1" : "0"; $binClick = dec2binf "1", (defined (param(-Name=>'Click' )) and (param(-Name=>'Click') eq 'K')) ? "1" : "0"; %convertMemberToBit = ( '' => '0', 'R' => '1', 'L' => '2', 'O' => '3', 'H' => '5', 'S' => '6' ); foreach ('R', 'L', 'O', 'H') { $bin{$_}{'volu'} = "0000000"; $bin{$_}{'inst'} = "000000"; } foreach ('R', 'L', 'O', 'H') { @splitRule = split(" ",param("Rule${_}")); $bin{$_}{'rule'} = dec2binf "5", pop(@splitRule); #print "rule$_:[", $bin{$_}{'rule'},"]
\n"; $bin{$_}{'oppo'} = dec2binf "3", $convertMemberToBit{defined($Opposite{$_}) ? $Opposite{$_}: ''}; #print "oppo$_:[", $bin{$_}{'oppo'},"]
\n"; if (defined($Rule{$_})){ $bin{$_}{'volu'} = dec2binf "7", $Vol{$_} ; $bin{$_}{'inst'} = dec2binf "6", $instr{$_} - 35; if (defined($Opposite{$_})) { $bin{$Opposite{$_}}{'volu'} = dec2binf "7", $Vol{$Opposite{$_}} ; $bin{$Opposite{$_}}{'inst'} = dec2binf "6", $instr{$Opposite{$_}} - 35; } } #print "volu$_:[", $bin{$_}{'volu'},"]
\n"; #print "inst$_:[", $bin{$_}{'inst'},"]
\n"; } @splitRule = split(" ",param("RuleS")); $bin{'S'}{'rule'} = dec2binf "5", pop(@splitRule); #print "ruleS:[", $bin{'S'}{'rule'},"]
\n"; $bin{'S'}{'oppo'} = dec2binf "3", $convertMemberToBit{defined($Opposite{'S'}) ? $Opposite{'S'}: ''}; #print "oppoS:[", $bin{'S'}{'oppo'},"]
\n"; $bin{'K'}{'volu'} = dec2binf "7", $Vol{'K'} ; $bin{'K'}{'inst'} = dec2binf "6", $instr{'K'} - 35; #print "voluK:[", $bin{'K'}{'volu'},"]
\n"; #print "instK:[", $bin{'K'}{'inst'},"]
\n"; foreach (1 .. 16) { $bin{'K'}{'click'} .= ($clickTime{$_}) ? 1 : 0; } #print "clickK:", $bin{'K'}{'click'},"
\n"; # Now the whole name $binName = join ( "", ( $binLengthOfSequences, $binFilter, $binRepeat, $binParrot, $binTempo, $binRightHand, $binLeftHand, $binBassDrum, $binHitHat, $binSilence, $binClick, $bin{'R'}{'rule'}, $bin{'R'}{'oppo'}, $bin{'R'}{'volu'}, $bin{'R'}{'inst'}, $bin{'L'}{'rule'}, $bin{'L'}{'oppo'}, $bin{'L'}{'volu'}, $bin{'L'}{'inst'}, $bin{'O'}{'rule'}, $bin{'O'}{'oppo'}, $bin{'O'}{'volu'}, $bin{'O'}{'inst'}, $bin{'H'}{'rule'}, $bin{'H'}{'oppo'}, $bin{'H'}{'volu'}, $bin{'H'}{'inst'}, $bin{'S'}{'rule'}, $bin{'S'}{'oppo'}, $bin{'K'}{'volu'}, $bin{'K'}{'inst'}, $bin{'K'}{'click'}) ); #print "Length New Name in bit: ", length($binName), " [$binName]
\n"; ($alphName) = convert64bin2alph ( ($binName) ); #print "Length New Name in caracter: ", length($alphName), " [$alphName]
\n"; $midiFileName = join ("", ($alphName, ".mid")); if (${midiFileName} =~ /\A(.*)\Z/) { ${midiFileName} = $1; } if ($compression{'selected'} eq 'not available'){ print $corpus->translate('None output format available.'), " ", $corpus->translate('Please, contact the WebMaster.'), "
\n"; return; } $compressionCommand = $compression{'command'}{$compression{'selected'}}; $downloadFileName = join ("", ($wwd, "/", "$alphName", $compression{'extension'}{$compression{'selected'}})); $confParameters{'debugMidi'} and print "compressionCommand: $compressionCommand
\n"; $confParameters{'debugMidi'} and print "downloadFileName: $downloadFileName
\n"; if (${downloadFileName} =~ /\A(.*)\Z/) { ${downloadFileName} = $1; } unless ( -f $downloadFileName ) { $ENV{'HOME'} = ""; unless (open (OUT,"|$confParameters{'tclInterpreter'} | $compressionCommand > $downloadFileName")) { warn "Could not open pipe : $! $?"; return ("Could not open pipe : $! $?"); }; ############################## # Here begins the tcl script # ############################## print OUT < $b} (keys (%combin))) { @trickNormal = split(//, $combin{$combinKey}{'normal'}); @trickInvert = split(//, $combin{$combinKey}{'invert'}); $doExoLoop = ($combin{$combinKey}{'loopable'} or not param(-Name=>'Filter')); $doExoInvert = ($combin{$combinKey}{'invertable'} or not param(-Name=>'Filter')); if ($doExoLoop) { foreach (1 .. param(-Name=>'Repeat')) { # the normal one, two times foreach $num (1 .. 2) { foreach $eachTime (1 .. $lengthOfSequences) { if ($clickTime{$eachTime}) { print OUT "midiput \$mf 1 {$time Note $channel ", $instr{'K'}, " ", $Vol{'K'}, " $division}\n"; } if (defined($instr{$trickNormal[$eachTime - 1]})){ print OUT "midiput \$mf 1 {$time Note $channel ", $instr{$trickNormal[$eachTime - 1]}, " ", $Vol{$trickNormal[$eachTime - 1]}, " $division}\n"; } $time += $division ; } } # parrot stuff here if ($doParrot){ foreach $num (1 .. 2) { foreach $eachTime (1 .. $lengthOfSequences) { if ($clickTime{$eachTime}) { print OUT "midiput \$mf 1 {$time Note $channel ", $instr{'K'}, " ", $Vol{'K'}, " $division}\n"; } $time += $division ; } } } } } if ($doExoInvert) { foreach (1 .. param(-Name=>'Repeat')) { # the normal one foreach $eachTime (1 .. $lengthOfSequences) { if ($clickTime{$eachTime}) { print OUT "midiput \$mf 1 {$time Note $channel ", $instr{'K'}, " ", $Vol{'K'}, " $division}\n"; } if (defined($instr{$trickNormal[$eachTime - 1]})){ print OUT "midiput \$mf 1 {$time Note $channel ", $instr{$trickNormal[$eachTime - 1]}, " ", $Vol{$trickNormal[$eachTime - 1]}, " $division}\n"; } $time += $division ; } # the invert one foreach $eachTime (1 .. $lengthOfSequences) { if ($clickTime{$eachTime}) { print OUT "midiput \$mf 1 {$time Note $channel ", $instr{'K'}, " ", $Vol{'K'}, " $division}\n"; } if (defined($instr{$trickInvert[$eachTime - 1]})){ print OUT "midiput \$mf 1 {$time Note $channel ", $instr{$trickInvert[$eachTime - 1]}, " ", $Vol{$trickInvert[$eachTime - 1]}, " $division}\n"; } $time += $division ; } # parrot stuff here if ($doParrot){ foreach $num (1 .. 2) { foreach $eachTime (1 .. $lengthOfSequences) { if ($clickTime{$eachTime}) { print OUT "midiput \$mf 1 {$time Note $channel ", $instr{'K'}, " ", $Vol{'K'}, " $division}\n"; } $time += $division ; } } } } } } $time += $division; print OUT <<"EOF"; midiput \$mf 1 {$time MetaEndOfTrack} # write midi file set df stdout midiwrite \$df \$mf flush \$df EOF ############################ # Here ends the tcl script # ############################ close (OUT) or do { print "The close pipe failed: $!
\n"; return("The close pipe failed: $!"); }; }; if ( -f $downloadFileName ) { print CGI::center(b($corpus->translate("Download the"), " ", $corpus->translate("midi file"), " ", a( {href=>$downloadFileName}, basename($downloadFileName) ), " ", int(((stat $downloadFileName)[7]/1024)+0.5), "Ko
\n" )); } } # xemacs has a big indentation problem with ${variable} reading ! # Sorry.