File Coverage

blib/lib/MIDI/XML/ControlChange.pm
Criterion Covered Total %
statement 11 74 14.8
branch 0 58 0.0
condition 0 3 0.0
subroutine 4 10 40.0
pod 6 6 100.0
total 21 151 13.9


line stmt bran cond sub pod time code
1             package MIDI::XML::ControlChange;
2              
3 1     1   12 use 5.006;
  1         1  
4 1     1   4 use strict;
  1         1  
  1         15  
5 1     1   3 use warnings;
  1         0  
  1         24  
6              
7 1     1   3 use MIDI::XML::Channel;
  1         1  
  1         715  
8              
9             our @ISA = qw(MIDI::XML::Channel);
10              
11             =head1 NAME
12              
13             MIDI::XML::ControlChange - MIDI Control Change messages.
14              
15             =head1 SYNOPSIS
16              
17             use MIDI::XML::ControlChange;
18             use MIDI::Track;
19              
20             $Control_Change = MIDI::XML::ControlChange->new();
21             $Control_Change->delta(384);
22             $Control_Change->channel(0);
23             $Control_Change->control(11);
24             $Control_Change->value(96);
25             @event = $Control_Change->as_event();
26             $midi_track = MIDI::Track->new();
27             push( @{$midi_track->events_r},\@event;
28             @xml = $Control_Change->as_MidiXML();
29             print join("\n",@xml);
30              
31             =head1 DESCRIPTION
32              
33             MIDI::XML::ControlChange is a class encapsulating MIDI Control Change messages.
34             A Control Change message includes either a delta time or absolute time as
35             implemented by MIDI::XML::Message and the MIDI Note Off event encoded
36             in 3 bytes as follows:
37              
38             1011cccc 0nnnnnnn 0vvvvvvv
39              
40             cccc = channel;
41              
42             nnnnnnn = control number
43              
44             vvvvvvv = value
45              
46             The classes for MIDI Control Change messages and the other six channel
47             messages are derived from MIDI::XML::Channel.
48              
49             =head2 EXPORT
50              
51             None by default.
52              
53             =cut
54              
55             our $VERSION = '0.02';
56              
57             #==========================================================================
58              
59             =head1 METHODS AND ATTRIBUTES
60              
61             =over 4
62              
63             =item $Control_Change = MIDI::XML::ControlChange->new()
64              
65             This creates a new MIDI::XML::ControlChange object.
66              
67             =item $Control_Change = MIDI::XML::ControlChange->new($event);
68              
69             Creates a new ControlChange object initialized with the values of a
70             MIDI::Event control_change array.
71              
72             =cut
73              
74             sub new {
75 0     0 1   my $class = shift;
76 0   0       $class = ref($class) || $class;
77              
78 0           my $self = {
79             '_Delta'=> undef,
80             '_Absolute'=> undef,
81             '_Channel'=> undef,
82             '_Control'=> undef,
83             '_Value'=> undef,
84             };
85 0 0         if (@_) {
86 0 0         if (ref($_[0]) eq 'ARRAY') {
    0          
    0          
87 0 0         if ($_[0][0] eq 'control_change') {
88 0           $self->{'_Delta'} = $_[0][1];
89 0           $self->{'_Channel'} = $_[0][2] & 0x0F;
90 0           $self->{'_Control'} = $_[0][3] & 0x7F;
91 0           $self->{'_Value'} = $_[0][4] & 0x7F;
92             }
93             } elsif (ref($_[0]) eq 'HASH') {
94 0           $self->{'_Value'} = 0;
95 0           foreach my $attr (keys %{$_[0]}) {
  0            
96 0 0         $self->{"_$attr"} = $_[0]->{$attr} unless ($attr =~ /^_/);
97             }
98 0 0         if ($_[0]->{'_ELEMENT'} eq 'AllSoundOff') {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
99 0           $self->{'_Control'} = 120;
100             } elsif ($_[0]->{'_ELEMENT'} eq 'ResetAllControllers') {
101 0           $self->{'_Control'} = 121;
102             } elsif ($_[0]->{'_ELEMENT'} eq 'LocalControl') {
103 0           $self->{'_Control'} = 122;
104 0 0         $self->{'_Value'} = ($_[0]->{'Value'} eq 'on') ? 127 : 0;
105             } elsif ($_[0]->{'_ELEMENT'} eq 'AllNotesOff') {
106 0           $self->{'_Control'} = 123;
107             } elsif ($_[0]->{'_ELEMENT'} eq 'OmniOff') {
108 0           $self->{'_Control'} = 124;
109             } elsif ($_[0]->{'_ELEMENT'} eq 'OmniOn') {
110 0           $self->{'_Control'} = 125;
111             } elsif ($_[0]->{'_ELEMENT'} eq 'MonoMode') {
112 0           $self->{'_Control'} = 126;
113             } elsif ($_[0]->{'_ELEMENT'} eq 'PolyMode') {
114 0           $self->{'_Control'} = 127;
115             }
116             } elsif (ref($_[0]) eq '') {
117 0 0         if ($_[0] eq 'control_change') {
118 0           $self->{'_Delta'} = $_[1];
119 0           $self->{'_Channel'} = $_[2] & 0x0F;
120 0           $self->{'_Control'} = $_[3] & 0x7F;
121 0           $self->{'_Value'} = $_[4] & 0x7F;
122             }
123             }
124             }
125              
126 0           bless($self,$class);
127 0           return $self;
128             }
129              
130             =item $delta_time = $Control_Change->delta() or $Control_Change->delta($delta_time);
131              
132             Returns the message time as a delta time or undef if it is an absolute
133             time. Optionally sets the message time to the specified delta time. To
134             avoid contradictory times, the absolute time is set to undef when a delta time
135             is set.
136              
137             This functionality is provided by the MIDI::XML::Message base class.
138              
139             =item $absolute_time = $Control_Change->absolute() or $Control_Change->absolute($absolute_time);
140              
141             Returns the message time as an absolute time or undef if it is a delta
142             time. Optionally sets the message time to the specified absolute time. To
143             avoid contradictory times, the delta time is set to undef when an absolute time
144             is set.
145              
146             This functionality is provided by the MIDI::XML::Message base class.
147              
148             =item $time = $Control_Change->time();
149              
150             Returns the message time, absolute or delta, whichever was last set.
151              
152             This functionality is provided by the MIDI::XML::Message base class.
153              
154             =item $channel = $Control_Change->channel() or $Control_Change->channel($channel);
155              
156             Returns and optionally sets the channel number. Channel numbers are limited
157             to the range 0-15.
158              
159             This functionality is provided by the MIDI::XML::Channel base class.
160              
161             =cut
162              
163             #==========================================================================
164              
165             =item $control = $Control_Change->control() or $Control_Change->control($control);
166              
167             Returns and optionally sets the control number. Control numbers are limited
168             to the range 0-127.
169              
170             =cut
171              
172             sub control {
173 0     0 1   my $self = shift;
174 0 0         if (@_) {
175 0           $self->{'_Control'} = (shift) & 0x7F;
176             }
177 0           return $self->{'_Control'};
178             }
179              
180             #==========================================================================
181              
182             =item $value = $Control_Change->value() or $Control_Change->value($value);
183              
184             Returns and optionally sets the control value. Values are limited
185             to the range 0-127.
186              
187             =cut
188              
189             sub value {
190 0     0 1   my $self = shift;
191 0 0         if (@_) {
192 0           $self->{'_Value'} = (shift) & 0x7F;
193             }
194 0           return $self->{'_Value'};
195             }
196              
197             #==========================================================================
198              
199             =item $ordinal = $Control_Change->ordinal();
200              
201             Returns a value to be used to order events that occur at the same time.
202              
203             =cut
204              
205             sub ordinal {
206 0     0 1   my $self = shift;
207 0 0         if ($self->{'_Control'} == 0 ) {
    0          
208 0           return 0x0201 + $self->{'_Channel'};
209             } elsif ($self->{'_Control'} == 32 ) {
210 0           return 0x0211 + $self->{'_Channel'};
211             }
212 0           return 0x0300 + $self->{'_Control'};
213             }
214              
215             #==========================================================================
216              
217             =item @event = $Control_Change->as_event();
218              
219             Returns a MIDI::Event control_change array initialized with the values of the
220             ControlChange object. MIDI::Event does not expect absolute times and will interpret
221             them as delta times. Calling this method when the time is absolute will not
222             generate a warning or error but it is unlikely that the results will be
223             satisfactory.
224              
225             =cut
226              
227             sub as_event {
228 0     0 1   my $self = shift;
229              
230             my @event = (
231             'control_change',
232             MIDI::XML::Message::time($self),
233             $self->{'_Channel'} & 0x0F,
234             $self->{'_Control'} & 0x7F,
235 0           $self->{'_Value'} & 0x7F
236             );
237 0           return @event;
238             }
239              
240             #==========================================================================
241              
242             =item @xml = $Control_Change->as_MidiXML();
243              
244             Returns an array of elements formatted according to the MidiXML DTD. These
245             elements may be assembled by track into entire documents with the following
246             suggested DOCTYPE declaration:
247              
248            
249             "-//Recordare//DTD MusicXML 0.7 MIDI//EN"
250             "http://www.musicxml.org/dtds/midixml.dtd">
251              
252             =back
253              
254             =cut
255              
256             sub as_MidiXML {
257 0     0 1   my $self = shift;
258 0           my @xml;
259              
260 0           my $ctl = $self->{'_Control'};
261 0           push @xml, MIDI::XML::Channel::as_MidiXML($self);
262 0 0         if ($ctl == 120) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
263 0           $xml[2] = "";
264             } elsif ($ctl == 121) {
265 0           $xml[2] = "";
266             } elsif ($ctl == 122) {
267 0 0         my $v = ($self->{'_Value'}) ? "on" : "off";
268 0           $xml[2] = "";
269             } elsif ($ctl == 123) {
270 0           $xml[2] = "";
271             } elsif ($ctl == 124) {
272 0           $xml[2] = "";
273             } elsif ($ctl == 125) {
274 0           $xml[2] = "";
275             } elsif ($ctl == 126) {
276 0           $xml[2] = "{'_Value'}\"/>";
277             } elsif ($ctl == 127) {
278 0           $xml[2] = "";
279             } else {
280 0           $xml[2] = "{'_Control'}\" Value=\"$self->{'_Value'}\"/>";
281             }
282 0           return @xml;
283             }
284              
285             #==========================================================================
286              
287              
288             return 1;
289             __END__