aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2017-11-02 10:37:29 +1300
committerTom Ryder <tom@sanctum.geek.nz>2017-11-02 10:37:29 +1300
commit3f5c9d2db38caeaebb66940015aa8dac8f363147 (patch)
treec15b0e1252ea966b2b11af051b73a76eac66c71e
parentMerge branch 'hotfix/v0.06' into develop (diff)
parentParse any number of fractional seconds (diff)
downloadMusic-Lyrics-LRC-3f5c9d2db38caeaebb66940015aa8dac8f363147.tar.gz
Music-Lyrics-LRC-3f5c9d2db38caeaebb66940015aa8dac8f363147.zip
Merge branch 'feature/fract-sec' into develop
* feature/fract-sec: Parse any number of fractional seconds
-rw-r--r--lib/Music/Lyrics/LRC.pm68
1 files changed, 30 insertions, 38 deletions
diff --git a/lib/Music/Lyrics/LRC.pm b/lib/Music/Lyrics/LRC.pm
index 10204d0..d9258a0 100644
--- a/lib/Music/Lyrics/LRC.pm
+++ b/lib/Music/Lyrics/LRC.pm
@@ -45,9 +45,13 @@ our %RE = (
\[ # Opening left bracket
(\d+) # Minutes, capture
: # Colon
- (\d{2}) # Seconds, capture
- [.] # Period
- (\d{2}) # Hundredths of a second, capture
+ ( # Seconds group, capture
+ \d{2} # Whole seconds
+ (?: # Group for fractional seconds
+ [.] # Period
+ \d+ # At least one digit
+ )? # End optional fractional seconds group
+ ) # End seconds group
\] # Closing right bracket
[\t ]* # Any tabs or spaces
(.*\S) # Lyric line, capture
@@ -67,11 +71,10 @@ my %parsers = (
# A lyric line
lyric => sub {
- my ( $self, %ts, $text );
- ( $self, @ts{qw(min sec csec)}, $text ) = @_;
+ my ( $self, $min, $sec, $text ) = @_;
# Calculate the number of milliseconds
- my $msec = $self->ts_to_msec( \%ts );
+ my $msec = $self->_min_sec_to_msec( $min, $sec );
# Push a lyric hashref onto our list
$self->add_lyric( $msec, $text );
@@ -208,11 +211,10 @@ sub save {
# Convert milliseconds to timestamp hash
my $msec = $lyric->{time};
- my %ts = %{ $self->msec_to_ts($msec) };
+ my ( $min, $sec ) = $self->_msec_to_min_sec($msec);
# Write the line to the file, counting the lines
- $lines += printf {$fh} "[%02u:%02u.%02u]%s\n",
- @ts{qw(min sec csec)}, $lyric->{text}
+ $lines += printf {$fh} "[%02u:%05.2f]%s\n", $min, $sec, $lyric->{text}
or die "Failed lyric write: $ERRNO\n";
}
@@ -220,32 +222,28 @@ sub save {
return $lines;
}
-# Factors for timestamp<->millisecond conversions
-our %MSF = (
- min => 60_000,
- sec => 1_000,
- csec => 10,
+# Named constants for the conversion functions
+# This stands for "millisecond factors"
+my %MSF = (
+ sec => 1_000,
+ min => 60_000,
);
-# Convert an LRC timestamp hashref to milliseconds
-sub ts_to_msec {
- my ( $self, $ts ) = @_;
+# Convert a minutes-seconds pair to milliseconds
+sub _min_sec_to_msec {
+ my ( $self, $min, $sec ) = @_;
my $msec = 0;
- for my $k ( keys %{$ts} ) {
- $msec += $ts->{$k} * $MSF{$k};
- }
+ $msec += int $min * $MSF{min};
+ $msec += $sec * $MSF{sec};
return $msec;
}
-# Convert milliseconds to an LRC timestamp hashref
-sub msec_to_ts {
+# Convert milliseconds to a minutes-seconds pair
+sub _msec_to_min_sec {
my ( $self, $msec ) = @_;
- my %ts;
- for my $k (qw(min sec csec)) {
- $ts{$k} = int $msec / $MSF{$k};
- $msec %= $MSF{$k};
- }
- return \%ts;
+ my $min = int $msec / $MSF{min};
+ my $sec = ( int $msec ) % $MSF{min} / $MSF{sec};
+ return ( $min, $sec );
}
1;
@@ -349,16 +347,6 @@ Load lyrics from the given readable filehandle.
Save lyrics to the given writeable filehandle.
-=head2 C<ts_to_msec(\%ts)>
-
-Convert the internal LRC timestamp hash structure to milliseconds. You are
-probably not interested in this.
-
-=head2 C<msec_to_ts($msec)>
-
-Convert milliseconds to the internal LRC timestamp hash structure. You are
-probably not interested in this, either.
-
=head1 DIAGNOSTICS
=over 4
@@ -445,6 +433,10 @@ may change in future revisions.
The format accepted here is very liberal, and needs to be tested with lots of
different LRC files from the wild.
+Fractional seconds of any length can be parsed, and preserved in the
+millisecond count return by C<lyrics()>, but any resolution beyond 2 decimal
+places is lost on C<save()>.
+
The test suite is skeletal, and needs a lot of fleshing out.
=head1 AUTHOR