1use constants::*;
7use types::{U7, Channel};
8use raw_message::{RawMessage};
9use RawMessage::*;
10use message::{Message};
11use Message::*;
12use utils::{mask7, status_byte, u14_to_msb_lsb};
13
14pub trait ToRawMessages {
20 fn to_raw_messages(&self) -> Vec<RawMessage>;
21}
22
23impl ToRawMessages for RawMessage {
24 fn to_raw_messages(&self) -> Vec<RawMessage> {
25 vec!(*self)
26 }
27}
28
29impl ToRawMessages for Message {
30 fn to_raw_messages(&self) -> Vec<RawMessage> {
31 match self {
32 &Start => vec!(Status(START)),
34 &TimingClock => vec!(Status(TIMING_CLOCK)),
35 &Continue => vec!(Status(CONTINUE)),
36 &Stop => vec!(Status(STOP)),
37 &ActiveSensing => vec!(Status(ACTIVE_SENSING)),
38 &SystemReset => vec!(Status(SYSTEM_RESET)),
39
40 &AllSoundOff(ch) => ControlChange(ch, 120, 0).to_raw_messages(),
42 &ResetAllControllers(ch) => ControlChange(ch, 121, 0).to_raw_messages(),
43 &LocalControlOff(ch) => ControlChange(ch, 122, 0).to_raw_messages(),
44 &LocalControlOn(ch) => ControlChange(ch, 122, 127).to_raw_messages(),
45 &AllNotesOff(ch) => ControlChange(ch, 123, 0).to_raw_messages(),
46
47 &ProgramChange(ch, no) => {
49 let sb = status_byte(PROGRAM_CHANGE, ch);
50 vec!(StatusData(sb, mask7(no)))
51 },
52 &ControlChange(ch, no, val) => {
53 vec!(cc(ch, mask7(no), mask7(val)))
54 },
55 &RPN7(ch, rpn, val) => {
56 let (rpn_msb, rpn_lsb) = u14_to_msb_lsb(rpn);
57 vec!(
58 cc(ch, CC_RPN_MSB, rpn_msb),
59 cc(ch, CC_RPN_LSB, rpn_lsb),
60 cc(ch, CC_DATA_ENTRY_MSB, mask7(val))
61 )
62 },
63 &RPN14(ch, rpn, val) => {
64 let (rpn_msb, rpn_lsb) = u14_to_msb_lsb(rpn);
65 let (val_msb, val_lsb) = u14_to_msb_lsb(val);
66 vec!(
67 cc(ch, CC_RPN_MSB, rpn_msb),
68 cc(ch, CC_RPN_LSB, rpn_lsb),
69 cc(ch, CC_DATA_ENTRY_MSB, val_msb),
70 cc(ch, CC_DATA_ENTRY_LSB, val_lsb)
71 )
72 },
73 &NRPN7(ch, nrpn, val) => {
74 let (nrpn_msb, nrpn_lsb) = u14_to_msb_lsb(nrpn);
75 vec!(
76 cc(ch, CC_NRPN_MSB, nrpn_msb),
77 cc(ch, CC_NRPN_LSB, nrpn_lsb),
78 cc(ch, CC_DATA_ENTRY_MSB, mask7(val))
79 )
80 },
81 &NRPN14(ch, nrpn, val) => {
82 let (nrpn_msb, nrpn_lsb) = u14_to_msb_lsb(nrpn);
83 let (val_msb, val_lsb) = u14_to_msb_lsb(val);
84 vec!(
85 cc(ch, CC_NRPN_MSB, nrpn_msb),
86 cc(ch, CC_NRPN_LSB, nrpn_lsb),
87 cc(ch, CC_DATA_ENTRY_MSB, val_msb),
88 cc(ch, CC_DATA_ENTRY_LSB, val_lsb)
89 )
90 },
91 &SysEx(manufacturer, ref data) => {
92 let mut output = Vec::new();
93 output.push(SYSEX);
94 output.extend(manufacturer.to_u7s());
95 output.extend(data.iter().map(|d| mask7(*d)));
96 output.push(SYSEX_EOX);
97 output.into_iter().map(|d| Raw(d)).collect()
98 },
99 &NoteOff(ch, no, vel) => {
100 let sb = status_byte(NOTE_OFF, ch);
101 vec!(StatusDataData(sb, mask7(no), mask7(vel)))
102 },
103 &NoteOn(ch, no, vel) => {
104 let sb = status_byte(NOTE_ON, ch);
105 vec!(StatusDataData(sb, mask7(no), mask7(vel)))
106 },
107 &PitchBend(ch, bend) => {
108 let sb = status_byte(PITCH_BEND, ch);
109 let (msb, lsb) = u14_to_msb_lsb(bend);
110 vec!(StatusDataData(sb, lsb, msb))
111 }
112 &PolyphonicPressure(ch, no, vel) => {
113 let sb = status_byte(POLYPHONIC_PRESSURE, ch);
114 vec!(StatusDataData(sb, mask7(no), mask7(vel)))
115 },
116 &ChannelPressure(ch, vel) => {
117 let sb = status_byte(CHANNEL_PRESSURE, ch);
118 vec!(StatusData(sb, mask7(vel)))
119 }
120 }
121 }
122}
123
124fn cc(ch: Channel, cc_no: U7, val: U7) -> RawMessage {
126 let sb = status_byte(CONTROL_CHANGE, ch);
127 StatusDataData(sb, cc_no, val)
128}
129
130#[cfg(test)]
131mod test {
132 use super::ToRawMessages;
133 use message::Message::*;
134 use raw_message::RawMessage::*;
135 use manufacturer::Manufacturer::*;
136 use types::Channel::*;
137
138 #[test]
139 fn test_message_to_raw_messages() {
140 assert_eq!(Start.to_raw_messages(), vec![Status(0b11111010)]);
145
146 assert_eq!(TimingClock.to_raw_messages(), vec![Status(0b11111000)]);
148
149 assert_eq!(Continue.to_raw_messages(), vec![Status(0b11111011)]);
151
152 assert_eq!(Stop.to_raw_messages(), vec![Status(0b11111100)]);
154
155 assert_eq!(ActiveSensing.to_raw_messages(), vec![Status(0b11111110)]);
157
158 assert_eq!(SystemReset.to_raw_messages(), vec![Status(0b11111111)]);
160
161 assert_eq!(AllSoundOff(Ch1).to_raw_messages(), vec![StatusDataData(176, 120, 0)]);
163
164 assert_eq!(ResetAllControllers(Ch1).to_raw_messages(), vec![StatusDataData(176, 121, 0)]);
166
167 assert_eq!(LocalControlOff(Ch1).to_raw_messages(), vec![StatusDataData(176, 122, 0)]);
169
170 assert_eq!(LocalControlOn(Ch1).to_raw_messages(), vec![StatusDataData(176, 122, 127)]);
172
173 assert_eq!(AllNotesOff(Ch1).to_raw_messages(), vec![StatusDataData(176, 123, 0)]);
175
176 assert_eq!(ProgramChange(Ch1, 0).to_raw_messages(), vec![StatusData(192, 0)]);
178 assert_eq!(ProgramChange(Ch1, 127).to_raw_messages(), vec![StatusData(192, 127)]);
179 assert_eq!(ProgramChange(Ch1, 128).to_raw_messages(), vec![StatusData(192, 0)]);
180
181 assert_eq!(ControlChange(Ch1, 0, 0).to_raw_messages(), vec![StatusDataData(176, 0, 0)]);
183 assert_eq!(ControlChange(Ch1, 0, 127).to_raw_messages(), vec![StatusDataData(176, 0, 127)]);
184 assert_eq!(ControlChange(Ch1, 0, 128).to_raw_messages(), vec![StatusDataData(176, 0, 0)]);
185 assert_eq!(ControlChange(Ch1, 127, 0).to_raw_messages(), vec![StatusDataData(176, 127, 0)]);
186 assert_eq!(ControlChange(Ch1, 128, 0).to_raw_messages(), vec![StatusDataData(176, 0, 0)]);
187
188 assert_eq!(RPN7(Ch1, 1000, 0).to_raw_messages(), vec![StatusDataData(176, 101, 7),
190 StatusDataData(176, 100, 104),
191 StatusDataData(176, 6, 0)]);
192
193 assert_eq!(RPN14(Ch1, 1000, 1001).to_raw_messages(), vec![StatusDataData(176, 101, 7),
195 StatusDataData(176, 100, 104),
196 StatusDataData(176, 6, 7),
197 StatusDataData(176, 38, 105)]);
198
199 assert_eq!(NRPN7(Ch1, 1000, 0).to_raw_messages(), vec![StatusDataData(176, 99, 7),
201 StatusDataData(176, 98, 104),
202 StatusDataData(176, 6, 0)]);
203
204 assert_eq!(NRPN14(Ch1, 1000, 1001).to_raw_messages(), vec![StatusDataData(176, 99, 7),
206 StatusDataData(176, 98, 104),
207 StatusDataData(176, 6, 7),
208 StatusDataData(176, 38, 105)]);
209
210 assert_eq!(SysEx(OneByte(100), vec![1, 2, 3, 4]).to_raw_messages(),
212 vec![Raw(0b11110000),
213 Raw(100),
214 Raw(1), Raw(2), Raw(3), Raw(4),
215 Raw(0b11110111)]);
216
217 assert_eq!(SysEx(OneByte(128), vec![1, 2, 3, 4, 128]).to_raw_messages(),
218 vec![Raw(0b11110000),
219 Raw(0),
220 Raw(1), Raw(2), Raw(3), Raw(4), Raw(0),
221 Raw(0b11110111)]);
222
223 assert_eq!(SysEx(ThreeByte(100, 101, 128), vec![1, 2, 3, 4]).to_raw_messages(),
224 vec![Raw(0b11110000),
225 Raw(100), Raw(101), Raw(0),
226 Raw(1), Raw(2), Raw(3), Raw(4),
227 Raw(0b11110111)]);
228
229 assert_eq!(NoteOff(Ch1, 0, 0).to_raw_messages(), vec![StatusDataData(128, 0, 0)]);
231 assert_eq!(NoteOff(Ch2, 127, 127).to_raw_messages(), vec![StatusDataData(129, 127, 127)]);
232 assert_eq!(NoteOff(Ch3, 128, 128).to_raw_messages(), vec![StatusDataData(130, 0, 0)]);
233
234 assert_eq!(NoteOn(Ch4, 0, 0).to_raw_messages(), vec![StatusDataData(147, 0, 0)]);
236 assert_eq!(NoteOn(Ch5, 127, 127).to_raw_messages(), vec![StatusDataData(148, 127, 127)]);
237 assert_eq!(NoteOn(Ch6, 128, 128).to_raw_messages(), vec![StatusDataData(149, 0, 0)]);
238
239 assert_eq!(PitchBend(Ch7, 0).to_raw_messages(), vec![StatusDataData(230, 0, 0)]);
241 assert_eq!(PitchBend(Ch8, 1000).to_raw_messages(), vec![StatusDataData(231, 104, 7)]);
242 assert_eq!(PitchBend(Ch9, 45000).to_raw_messages(), vec![StatusDataData(232, 72, 95)]);
243 assert_eq!(PitchBend(Ch10, 12232).to_raw_messages(), vec![StatusDataData(233, 72, 95)]);
244
245 assert_eq!(PolyphonicPressure(Ch11, 0, 0).to_raw_messages(),
247 vec![StatusDataData(170, 0, 0)]);
248 assert_eq!(PolyphonicPressure(Ch12, 127, 127).to_raw_messages(),
249 vec![StatusDataData(171, 127, 127)]);
250 assert_eq!(PolyphonicPressure(Ch13, 128, 128).to_raw_messages(),
251 vec![StatusDataData(172, 0, 0)]);
252
253 assert_eq!(ChannelPressure(Ch14, 0).to_raw_messages(), vec![StatusData(221, 0)]);
255 assert_eq!(ChannelPressure(Ch15, 127).to_raw_messages(), vec![StatusData(222, 127)]);
256 assert_eq!(ChannelPressure(Ch16, 128).to_raw_messages(), vec![StatusData(223, 0)]);
257 }
258}
259