File Coverage

blib/lib/Music/PitchNum/German.pm
Criterion Covered Total %
statement 39 39 100.0
branch 20 22 90.9
condition n/a
subroutine 7 7 100.0
pod 2 2 100.0
total 68 70 97.1


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   6940 use 5.010000;
  2         4  
12 2     2   6 use Moo::Role;
  2         2  
  2         9  
13 2     2   883 use POSIX qw/floor/;
  2         4389  
  2         12  
14 2     2   923 use Scalar::Util qw/looks_like_number/;
  2         2  
  2         743  
15              
16             our $VERSION = '0.08';
17              
18             ##############################################################################
19             #
20             # ATTRIBUTES
21              
22             has NOTE2NUM => (
23             is => 'rw',
24             default => sub {
25             { C => 0,
26             D => 2,
27             E => 4,
28             F => 5,
29             G => 7,
30             A => 9,
31             B => 10,
32             H => 11,
33             };
34             },
35             );
36             # NOTE lilypond picky about "ees" and "aes" in deutsch mode
37             has NUM2NOTE => (
38             is => 'rw',
39             default => sub {
40             { 0 => 'c',
41             1 => 'des',
42             2 => 'd',
43             3 => 'es',
44             4 => 'e',
45             5 => 'f',
46             6 => 'ges',
47             7 => 'g',
48             8 => 'as',
49             9 => 'a',
50             10 => 'b',
51             11 => 'h',
52             };
53             },
54             );
55              
56             has ignore_octave => (
57             is => 'rw',
58             coerce => sub {
59             $_[0] ? 1 : 0;
60             },
61             default => 0,
62             );
63              
64             ##############################################################################
65             #
66             # METHODS
67              
68             sub pitchname {
69 14     14 1 53 my ( $self, $number ) = @_;
70 14 100       42 die "need a number for pitchname\n" if !looks_like_number $number;
71              
72 13         38 my $note = $self->NUM2NOTE->{ $number % 12 };
73              
74 13 100       26 if ( !$self->ignore_octave ) {
75 10         646 my $octave = floor( $number / 12 ) - 1;
76 10 100       21 if ( $octave > 3 ) {
    100          
77 7         12 $note .= (q{'}) x ( $octave - 3 );
78             } elsif ( $octave < 3 ) {
79 2         4 $note .= (q{,}) x ( 3 - $octave );
80             }
81             }
82              
83 13         101 return $note;
84             }
85              
86             sub pitchnum {
87 16     16 1 22 my ( $self, $name ) = @_;
88              
89             # already a pitch number, but nix the decimal foo
90 16 50       50 return int $name if looks_like_number $name;
91              
92 16         11 my $pitchnum;
93              
94             # octave indication only follows accidental, accidental only after note
95             # plus complication for "as", "ases", "es", "eses" special cases
96 16 50       113 if (
97             $name =~ m/ (? [A-Ha-h] )
98             (? es(?:es)? | is(?:is)? | (?<=[AEae]) s(?:es)? )?
99             (? [,]{1,10}|[']{1,10} )?
100             /x
101             ) {
102 16     1   80 my $octave = $+{octave};
  1         400  
  1         267  
  1         155  
103 16         40 my $chrome = $+{chrome};
104 16         34 my $note = $+{note};
105              
106 16         45 $pitchnum = $self->NOTE2NUM->{ uc $note } + 12 * 4;
107              
108 16 100       21 if ( defined $octave ) {
109 15 100       33 $pitchnum += 12 * length($octave) * ( $octave =~ m/[,]/ ? -1 : 1 );
110             }
111              
112 16 100       24 if ( defined $chrome ) {
113 8 100       15 if ( $chrome =~ m/^s/ ) { # as/ases klugery
114 4         7 $chrome = "e$chrome";
115             }
116 8         10 $chrome =~ tr/s//d;
117 8 100       19 $pitchnum += length($chrome) * ( $chrome =~ m/e/ ? -1 : 1 );
118             }
119             }
120              
121 16         45 return $pitchnum;
122             }
123              
124             1;
125             __END__