#!/usr/bin/perl -s

use Text::RewriteRules;
use Term::ReadKey;
our($c,$m,$keyb);
my $qt = $m || 600;
my $co = [4,4];
if    ($c =~ m!(\d)/(\d)! ) {$co = [$1,$2];}
elsif ($c =~ m!(\d)! )      {$co = [$1,4 ];}
$keyb ||= 1;

use Audio::Data;
use Audio::Play;
use strict;

my $svr = Audio::Play->new  or die ("cant open audio\n"); 

my $key="";
my $header = "X:1\nM:$co->[0]/$co->[1]\nQ: 1/4=60\nL:1/4\nK:C";
my $out = "";
$|=1;

my $outputfile = shift || "_out";
open(F,">", $outputfile) or die("can open $outputfile\n");

my @nomes= split(/ +/,q(c c# d d# e f f# g g# a a# b C C# D D# E F));
my @escala;
if ($keyb == 1){ binmode(STDIN,":utf8");
      @escala = (split("","awsedftgyhujkolpç[")); }
elsif ($keyb == 2){ binmode(STDIN,":utf8");
      keybalt(1);
      @escala = (split("","%?<azsxcfvgbnjmk,l.-[\$r&@")); 
      unshift(@nomes,"b,");
      unshift(@nomes,"a#,");
      unshift(@nomes,"a,");
      unshift(@nomes,"g#,");
      unshift(@nomes,"g,");
      unshift(@nomes,"f#,");
      unshift(@nomes,"f,");
#      push(@nomes,"F#");
#      push(@nomes,"G,");
#      push(@nomes,"G#,");
#      push(@nomes,"A,");
}
else{ @escala = (split("","<azsxcfvgbhnmk,l.-")); }

my %h;
@h{@escala}=(1 .. @escala);

# do # re # mi fa # sol # la # si  DO # RE # MI 
my %n;
@n{@escala}=@nomes;
# for (@escala){ print ("$_  =  $n{$_} = $h{$_}\n"); }

# C1 * k^12 = C2     => 
# k ^12 = 2          => 
# log(k)*12 = log(2) => 
# log(k) = log(2)/12 =>
# k = exp(log(2)/12) =>
my $k=1.0594630943593;  

my $t=0;
my $n1=0;
my $n=0;
my $last=0;

ReadMode 4; # Turn off controls keys

while (($key = ReadKey(0.001)||"") ne "q"){
  $n++;
  if ($key)         { 
    if($key =~ /[\s]\?\?\?\?/){ warn("??$key\n") }
    else{
       $out .= i(($n-$last)*8/$qt). " $n{$key}";
       $last=$n;
       my $a = Audio::Data->new(rate=> 8000, silence => 0.001);
       $a->tone(320*( $k**($h{$key}-1)),0.06,0.3);
       #$a->silence(0.05);
       $svr->play($a);
       $svr->flush;
       $n+=61;
    }
  }
  else{
      $n++ ;
      select(undef,undef,undef,0.001);
  }
  if ($n > $n1) { 
       $n1 += $qt;
       my $a = Audio::Data->new(rate=> 8000, silence => 0.001);
       if($t++ % $co->[0] == 0 ) { 
           $a->tone(220*22,0.01,0.3);
           $out .=  i(($n-$last)*8/$qt). "|";
           $last=$n;
       }
       else { $a->tone(220*28,0.01,0.3); }
       $svr->play($a);
       $svr->flush;
       $n += 11;
  }
}

 my $rr1 = toabc($out);
 my $rr2 = ff($rr1);
 print F "$header\n$rr2\n";
 print "$header\n$rr2\n";
 keybalt(0);
 ReadMode 0; # Reset tty mode before exiting

sub i{ int($_[0]+0.5); }

RULES/m toabc
\|[012]==>|
([^\|])([012])\s*\|(\d+)==>|$1$3!! $3 >= 4
(.)==>$1
(\n)==>$1
ENDRULES

RULES/m ff
(11|12|13|14)==>3/2
(15|16|17|18)==>2
(24|23|25|22|26)==>3
(30|31|32)==>4
(7|8|9)==>1
(10|21|19|20|2)==>?
(6)==>3/4
(3|4|5)==>/2
(.|\n)==>$1
ENDRULES

sub keybalt{
  my $k1={
    23 => "exclam",     #tab
    35 => "equal",
    50 => "percent",    #1
    51 => "ampersand",  #3
    62 => "dollar",     #2
    98 => "at Up",      #4
    117 => "Up",
    };

  my $k2={
    23 => "Tab ISO_Left_Tab",
    35 => "dead_acute dead_grave dead_tilde dead_macron",
    50 => "Shift_L",
    51 => "dead_tilde dead_circumflex",
    62 => "Shift_R",
    98 => "Up",
    };

  if($_[0]){
    system ("xmodmap -e 'remove Shift = 50' -e 'remove Shift = 62' ".
         join(" ",map {"-e 'keycode $_ = $k1->{$_}'"} keys %$k1));
  }
  else {
    system ("xmodmap -e 'add Shift = 50' -e 'add Shift = 62' ".
         join(" ",map {"-e 'keycode $_ = $k2->{$_}'"} keys %$k2));
  }
}

__END__
