Advertisement
Guest User

Untitled

a guest
Jan 9th, 2021
382
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.29 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4. use strict;
  5.  
  6. use File::Basename;
  7. use POSIX;
  8.  
  9. my %cfg = ( SOURCE => "0,0", TARGET => "0,100", TIMETARGET => 2, MARK => '*', TARGETMARK => 'O' );
  10. my @beats;
  11. my $total = 0;
  12.  
  13. sub fmttime($) {
  14.     my $time = sprintf "%.02f", shift;
  15.     my ($sec,$frac) = $time =~ /^(\d+)(\..*)$/;
  16.     my $min = int($sec/60);
  17.     $sec -= $min*60;
  18.     my $hr = int($min/60);
  19.     $min -= $hr*60;
  20.     return sprintf "%d:%02d:%02d%s", $hr,$min,$sec,$frac;
  21. }
  22.  
  23. sub interp {
  24.     my ($src,$dst,$frac,$dur) = @_;
  25.     my ($sx,$sy) = split /,/, $src;
  26.     my ($dx,$dy) = split /,/, $dst;
  27.     return sprintf "%d,%d",
  28.         ($sx + ($dx - $sx) * $frac/$dur),
  29.         ($sy + ($dy - $sy) * $frac/$dur);
  30. }
  31.  
  32. sub durations {
  33.     my @dur = split /,/, shift;
  34.     $_ = m#^(\d+)/(\d+)$# ? $2 / $1 : 1 / $_ for @dur;
  35.     return @dur;
  36. }
  37.  
  38. sub readbeats {
  39.   @beats = ();
  40.   $total = 0;
  41.   $cfg{$_} = undef for qw (BPM LAST FIRST MID MIDNUM);
  42.  
  43.   my $f = shift;
  44.   while (<$f>) {
  45.     chomp;
  46.     my $line = $_;
  47.     s/\s*#.*$//;
  48.     if (/^BREAK/) {
  49.         return $total;
  50.     } elsif (m#^(\d+)@([\d.,/]+)\s*(\S*)$#) {
  51.         push @beats, [$1, $2, $3];
  52.         $total += $1 * $_ for durations $2;
  53.     } elsif (/^(\w+)=(.+)$/) {
  54.         $cfg{$1} = $2;
  55.     } elsif (/^\s*$/) {
  56.     } else {
  57.         die "Can't parse line $.: $line\n";
  58.     }
  59.   }
  60.   return $total;
  61. }
  62.  
  63. my $patname = shift;
  64.  
  65. my ($basename,$path) = fileparse $patname, qr/\.[^.]+$/;
  66. #$basename = "$path/$basename";
  67.  
  68. my $hdrname = "beat/$basename.header";
  69. open my $hdr, "<", $hdrname or die "Can't read $hdrname: $!\n";
  70.  
  71. my $assname = "$basename.ass";
  72. open my $ass, ">", $assname or die "Can't write $assname: $!\n";
  73. print $ass $_ while <$hdr>;
  74.  
  75. my $lasttarget = 0;
  76. open my $in, "<", "beat/$patname" or die "Can't read $patname: $!\n";
  77. while (readbeats $in) {
  78.  
  79. die "Need at least one beat!\n" unless $total > 0;
  80.  
  81. my $finish = $cfg{FINISH} || $cfg{TARGET};
  82. my $timefinish = $cfg{TIMEFINISH} || 0;
  83.  
  84. my ($base,$bpm);
  85.  
  86. if ($cfg{BPM}) {
  87.     $bpm = $cfg{BPM};
  88.     $base = 60/$cfg{BPM};
  89. } else {
  90.     $cfg{MID} ||= $cfg{LAST};
  91.     $cfg{MIDNUM} ||= $total;
  92.  
  93.     my $time = $cfg{MID}-$cfg{FIRST};
  94.     $base = $time / ($cfg{MIDNUM} - 1);
  95.     $bpm = 60 / $base;
  96. }
  97. my $time = $total * $base;
  98. printf "$total full beats over $time sec, %.3f base beat time (%.1f BPM)\n", $base, $bpm;
  99.  
  100. my $targettime = $cfg{FIRST} - $cfg{TIMETARGET};
  101. $targettime = $lasttarget if $targettime < $lasttarget;
  102. $lasttarget = $targettime;
  103.  
  104. printf $ass "Dialogue: 0,%s,%s,Target,,0,0,0,,{\\pos($cfg{TARGET})}$cfg{TARGETMARK}\n",
  105.     fmttime $targettime, fmttime $cfg{FIRST}+$total*$base;
  106.  
  107. my $beat = 0;
  108. for my $entry (@beats) {
  109.     my $start = $beat - 1;
  110.     while ($entry->[0]-- > 0) {
  111.         my @durations = durations $entry->[1];
  112.         my @marks = split /,/, $entry->[2];
  113.         while (@durations) {
  114.         my $time = $cfg{FIRST} + $beat * $base;
  115.         my $durtarget = $cfg{TIMETARGET};
  116.         my $durfinish = $timefinish;
  117.         my $src = $cfg{SOURCE};
  118.         my $mark = shift(@marks) || $cfg{MARK};
  119.         $mark =~ s/\\R/$beat - $start/e;
  120.         $mark =~ s/\\T/$beat/e;
  121.         if ($time < $durtarget){
  122.             $src = interp $src, $cfg{TARGET}, $durtarget-$time, $durtarget;
  123.             $durtarget = $time;
  124.         }
  125.  
  126.         my $dur = shift @durations;
  127.         printf $ass "Dialogue: 0,%s,%s,Beat%d,,0,0,0,,{\\move(%s,$finish)}%s\n",
  128.             fmttime $time - $durtarget, fmttime $time + $durfinish,
  129.             ceil(1/$dur), $src, $mark;
  130.         $beat += $dur;
  131.         }
  132.     }
  133. }
  134.  
  135. }
  136.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement