File Coverage

blib/lib/Music/PitchNum/German.pm
Criterion Covered Total %
statement 40 40 100.0
branch 20 22 90.9
condition 2 2 100.0
subroutine 7 7 100.0
pod 2 2 100.0
total 71 73 97.2


line stmt bran cond sub pod time code
1             # -*- Perl -*-
2             #
3             # For BACH, or, compatibility with the lilypond "\language deutsch"
4             # format. See Dutch.pm of this distribution for the default lilypond
5             # format (nederlands).
6             #
7             # Run perldoc(1) on this file for additional documentation.
8              
9             package Music::PitchNum::German;
10              
11 2     2   8461 use 5.010000;
  2         6  
12 2     2   7 use Moo::Role;
  2         8  
  2         11  
13 2     2   1075 use POSIX qw/floor/;
  2         5173  
  2         9  
14 2     2   1016 use Scalar::Util qw/looks_like_number/;
  2         3  
  2         814  
15              
16             our $VERSION = '0.09';
17              
18             my %NOTE2NUM = (
19             C => 0,
20             D => 2,
21             E => 4,
22             F => 5,
23             G => 7,
24             A => 9,
25             B => 10,
26             H => 11,
27             );
28              
29             # NOTE lilypond picky about "ees" and "aes" in deutsch mode
30             my %NUM2NOTE = (
31             0 => 'c',
32             1 => 'des',
33             2 => 'd',
34             3 => 'es',
35             4 => 'e',
36             5 => 'f',
37             6 => 'ges',
38             7 => 'g',
39             8 => 'as',
40             9 => 'a',
41             10 => 'b',
42             11 => 'h',
43             );
44              
45             ##############################################################################
46             #
47             # METHODS
48              
49             sub pitchname {
50 14     14 1 11303 my ( $self, $number, %params ) = @_;
51 14 100       53 die "need a number for pitchname\n" if !looks_like_number $number;
52              
53 13   100     46 $params{ignore_octave} //= 0;
54              
55 13         24 my $note = $NUM2NOTE{ $number % 12 };
56              
57 13 100       24 if ( !$params{ignore_octave} ) {
58 10         42 my $octave = floor( $number / 12 ) - 1;
59 10 100       22 if ( $octave > 3 ) {
    100          
60 7         12 $note .= (q{'}) x ( $octave - 3 );
61             } elsif ( $octave < 3 ) {
62 2         6 $note .= (q{,}) x ( 3 - $octave );
63             }
64             }
65              
66 13         51 return $note;
67             }
68              
69             sub pitchnum {
70 16     16 1 25 my ( $self, $name ) = @_;
71              
72             # already a pitch number, but nix the decimal foo
73 16 50       55 return int $name if looks_like_number $name;
74              
75 16         14 my $pitchnum;
76              
77             # octave indication only follows accidental, accidental only after note
78             # plus complication for "as", "ases", "es", "eses" special cases
79 16 50       91 if (
80             $name =~ m/ (? [A-Ha-h] )
81             (? es(?:es)? | is(?:is)? | (?<=[AEae]) s(?:es)? )?
82             (? [,]{1,10}|[']{1,10} )?
83             /x
84             ) {
85 16     1   81 my $octave = $+{octave};
  1         453  
  1         315  
  1         184  
86 16         48 my $chrome = $+{chrome};
87 16         39 my $note = $+{note};
88              
89 16         31 $pitchnum = $NOTE2NUM{ uc $note } + 12 * 4;
90              
91 16 100       29 if ( defined $octave ) {
92 15 100       38 $pitchnum += 12 * length($octave) * ( $octave =~ m/[,]/ ? -1 : 1 );
93             }
94              
95 16 100       29 if ( defined $chrome ) {
96 8 100       19 if ( $chrome =~ m/^s/ ) { # as/ases klugery
97 4         7 $chrome = "e$chrome";
98             }
99 8         14 $chrome =~ tr/s//d;
100 8 100       21 $pitchnum += length($chrome) * ( $chrome =~ m/e/ ? -1 : 1 );
101             }
102             }
103              
104 16         52 return $pitchnum;
105             }
106              
107             1;
108             __END__