File Coverage

blib/lib/idi.pm
Criterion Covered Total %
statement 62 62 100.0
branch 6 6 100.0
condition n/a
subroutine 25 25 100.0
pod 13 13 100.0
total 106 106 100.0


line stmt bran cond sub pod time code
1             package idi;
2              
3             # ABSTRACT: Easy, command-line MIDI
4              
5 1     1   705 use strict;
  1         2  
  1         29  
6 1     1   4 use warnings;
  1         2  
  1         23  
7              
8 1     1   507 use Moo;
  1         11068  
  1         5  
9 1     1   1875 use strictures 2;
  1         1641  
  1         41  
10 1     1   622 use File::Slurper qw(read_binary);
  1         13646  
  1         65  
11 1     1   748 use File::Temp qw(tempfile);
  1         17194  
  1         68  
12 1     1   669 use MIDI::Simple ();
  1         21175  
  1         39  
13 1     1   450 use Music::Tempo qw(bpm_to_ms);
  1         583  
  1         70  
14 1     1   446 use namespace::clean;
  1         11562  
  1         7  
15              
16 1     1   308 use Exporter qw(import);
  1         2  
  1         227  
17             our @EXPORT = qw(
18             get_score
19             b
20             c
21             d
22             e
23             n
24             o
25             p
26             r
27             t
28             v
29             w
30             x
31             );
32              
33             our $VERSION = '0.0305';
34              
35             my $self;
36              
37             sub BEGIN {
38 1     1   8 has filename => (
39             is => 'rw',
40             builder => 1,
41             );
42             sub _build_filename {
43 1     1   1565 my ($fh, $filename) = tempfile('idi-XXXX',
44             DIR => '.',
45             SUFFIX => '.mid',
46             UNLINK => 1,
47             );
48 1         690 return $filename;
49             }
50              
51             has score => (
52             is => 'ro',
53 1         11 default => sub { MIDI::Simple->new_score },
54 1         20357 );
55              
56             has play => (
57             is => 'rw',
58 1         19 default => sub { 1 },
59 1         301 );
60              
61             has is_written => (
62             is => 'rw',
63 1         30 default => sub { 0 },
64 1         285 );
65              
66 1         277 $self = __PACKAGE__->new;
67             }
68              
69             sub END {
70             if ($self->play) {
71             $self->score->write_score($self->filename) unless $self->is_written;
72             my $content = read_binary($self->filename);
73             print $content;
74             }
75             }
76              
77             sub get_score {
78 1     1 1 607 return $self->score;
79             }
80              
81             sub b {
82 1     1 1 4 my ($bpm) = @_;
83 1         5 $self->score->set_tempo(bpm_to_ms($bpm) * 1000);
84             }
85              
86             sub c {
87 1     1 1 1221 $self->score->Channel(@_);
88             }
89              
90             sub d {
91 1     1 1 1109 $self->score->Duration(@_);
92             }
93              
94             sub e {
95 1     1 1 361 my ($value) = @_;
96 1         5 $self->play($value);
97             }
98              
99             sub n {
100 2     2 1 568 $self->score->n(@_);
101             }
102              
103             sub o {
104 1     1 1 1201 $self->score->Octave(@_);
105             }
106              
107             sub p {
108 1     1 1 553 $self->score->patch_change(@_);
109             }
110              
111             sub r {
112 1     1 1 678 $self->score->r(@_);
113             }
114              
115             sub t {
116 2     2 1 1170 my ($signature) = @_;
117 2         9 my ($beats, $divisions) = split /\//, $signature;
118 2 100       17 $self->score->time_signature(
    100          
119             $beats,
120             ($divisions == 8 ? 3 : 2),
121             ($divisions == 8 ? 24 : 18 ),
122             8
123             );
124             }
125              
126             sub v {
127 1     1 1 1120 $self->score->Volume(@_);
128             }
129              
130             sub w {
131 2     2 1 1323 my ($name) = @_;
132 2 100       6 if ($name) {
133 1         4 $self->filename($name);
134             }
135             else {
136 1         4 $name = $self->filename;
137             }
138 2         15 $self->score->write_score($name);
139 2         1676 $self->is_written(1);
140             }
141              
142             sub x {
143 1     1 1 404 $self->score->noop(@_);
144             }
145              
146             1;
147              
148             =head1 NAME
149              
150             idi - Easy, command-line MIDI
151              
152             =head1 SYNOPSIS
153              
154             $ perl -Midi -E'x(qw(c1 f o5)); n(qw(qn Cs)); n("F"); n("Ds"); n(qw(hn Gs_d1))' | timidity -
155              
156             # Compare with:
157             $ perl -MMIDI::Simple -E'new_score; noop qw(c1 f o5); n qw(qn Cs); n "F"; n "Ds"; n qw(hn Gs_d1); write_score shift()' idi.mid
158             $ timidity idi.mid
159              
160             =head1 DESCRIPTION
161              
162             Easy, command-line MIDI!
163              
164             =head1 FUNCTIONS
165              
166             =head2 b
167              
168             b(100)
169              
170             Set BPM
171              
172             =head2 c
173              
174             c(15)
175              
176             Channel
177              
178             Default: C<0>
179              
180             =head2 d
181              
182             d(128)
183              
184             Duration
185              
186             Default: C<96>
187              
188             =head2 e
189              
190             e(0)
191              
192             Play at end
193              
194             Default: C<1>
195              
196             =head2 get_score
197              
198             Return the L score object.
199              
200             =head2 n
201              
202             n(@note_spec)
203              
204             Add note. See the L documentation for what a
205             "note_spec" is.
206              
207             =head2 o
208              
209             o(3)
210              
211             Octave
212              
213             Default: C<5>
214              
215             =head2 p
216              
217             p($channel, $patch_number)
218              
219             Patch
220              
221             Default: C<0, 0> (channel 0, piano)
222              
223             =head2 r
224              
225             r($note_duration)
226              
227             Add rest. See the L documentation for what
228             "note_durations" are valid.
229              
230             =head2 t
231              
232             t("$numerator/$denominator")
233              
234             Time signature
235              
236             Default: C
237              
238             =head2 v
239              
240             v(127)
241              
242             Volume
243              
244             Default: C<64>
245              
246             =head2 w
247              
248             w("filename.mid")
249              
250             Write score to a file.
251              
252             =head2 x
253              
254             No-op (with C)
255              
256             =for Pod::Coverage filename
257             =for Pod::Coverage score
258             =for Pod::Coverage play
259             =for Pod::Coverage is_written
260              
261             =head1 SEE ALSO
262              
263             The F file in this distribution
264              
265             L
266              
267             L
268              
269             L
270              
271             L
272              
273             L
274              
275             L
276              
277             L
278              
279             L
280              
281             =head1 AUTHOR
282              
283             Gene Boggs
284              
285             =head1 COPYRIGHT AND LICENSE
286              
287             This software is Copyright (c) 2022 by Gene Boggs.
288              
289             This is free software, licensed under: The Artistic License 2.0 (GPL Compatible)
290              
291             =cut