@@ -141,3 +141,216 @@ TEST (UMPChannelVoiceTests, Midi2ToMidi1Translation)
141141 ASSERT_TRUE (m2.has_value ());
142142 EXPECT_EQ (*m2, makeMidi1NoteOffMessage (3 , 9 , 66 , Velocity { uint16_t { 0x1234 } }));
143143}
144+
145+ TEST (UMPChannelVoiceTests, ProgramChangeMessages)
146+ {
147+ EXPECT_TRUE (isProgramChangeMessage (makeMidi1ProgramChangeMessage (0 , 5 , 42 )));
148+ EXPECT_EQ (getProgramValue (makeMidi1ProgramChangeMessage (0 , 5 , 42 )), 42 );
149+
150+ EXPECT_TRUE (isProgramChangeMessage (makeMidi2ProgramChangeMessage (1 , 7 , 99 )));
151+ EXPECT_EQ (getProgramValue (makeMidi2ProgramChangeMessage (1 , 7 , 99 )), 99 );
152+ }
153+
154+ TEST (UMPChannelVoiceTests, Midi1ToMidi2Translation)
155+ {
156+ auto midi1NoteOn = makeMidi1NoteOnMessage (2 , 3 , 60 , Velocity { uint7_t { 100 } });
157+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1NoteOn });
158+ ASSERT_TRUE (result.has_value ());
159+ EXPECT_TRUE (isNoteOnMessage (*result));
160+
161+ auto midi1NoteOff = makeMidi1NoteOffMessage (1 , 4 , 72 , Velocity { uint7_t { 64 } });
162+ result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1NoteOff });
163+ ASSERT_TRUE (result.has_value ());
164+ EXPECT_TRUE (isNoteOffMessage (*result));
165+ }
166+
167+ TEST (UMPChannelVoiceTests, Midi1ZeroVelocityNoteOnToMidi2)
168+ {
169+ auto midi1NoteOn = makeMidi1NoteOnMessage (2 , 3 , 60 , Velocity { uint7_t { 0 } });
170+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1NoteOn });
171+ ASSERT_TRUE (result.has_value ());
172+ EXPECT_TRUE (isNoteOffMessage (*result));
173+ }
174+
175+ TEST (UMPChannelVoiceTests, Midi1ControlChangeToMidi2)
176+ {
177+ auto midi1CC = makeMidi1ControlChangeMessage (3 , 7 , 10 , ControllerValue { uint7_t { 64 } });
178+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1CC });
179+ ASSERT_TRUE (result.has_value ());
180+ EXPECT_TRUE (isControlChangeMessage (*result));
181+ }
182+
183+ TEST (UMPChannelVoiceTests, Midi1ProgramChangeToMidi2)
184+ {
185+ auto midi1PC = makeMidi1ProgramChangeMessage (4 , 8 , 42 );
186+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1PC });
187+ ASSERT_TRUE (result.has_value ());
188+ EXPECT_TRUE (isProgramChangeMessage (*result));
189+ }
190+
191+ TEST (UMPChannelVoiceTests, Midi1PolyPressureToMidi2)
192+ {
193+ auto midi1PP = makeMidi1PolyPressureMessage (5 , 9 , 72 , ControllerValue { uint7_t { 80 } });
194+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1PP });
195+ ASSERT_TRUE (result.has_value ());
196+ EXPECT_TRUE (isPolyPressureMessage (*result));
197+ }
198+
199+ TEST (UMPChannelVoiceTests, Midi1ChannelPressureToMidi2)
200+ {
201+ auto midi1CP = makeMidi1ChannelPressureMessage (6 , 10 , ControllerValue { uint7_t { 70 } });
202+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1CP });
203+ ASSERT_TRUE (result.has_value ());
204+ EXPECT_TRUE (isChannelPressureMessage (*result));
205+ }
206+
207+ TEST (UMPChannelVoiceTests, Midi1PitchBendToMidi2)
208+ {
209+ auto midi1PB = makeMidi1PitchBendMessage (7 , 11 , PitchBend { uint14_t { 8192 } });
210+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1PB });
211+ ASSERT_TRUE (result.has_value ());
212+ EXPECT_TRUE (isChannelPitchBendMessage (*result));
213+ }
214+
215+ TEST (UMPChannelVoiceTests, Midi2PolyPressureToMidi1)
216+ {
217+ auto midi2PP = makeMidi2PolyPressureMessage (2 , 5 , 64 , ControllerValue { 0x80000000u });
218+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2PP });
219+ ASSERT_TRUE (result.has_value ());
220+ EXPECT_TRUE (isPolyPressureMessage (*result));
221+ }
222+
223+ TEST (UMPChannelVoiceTests, Midi2ControlChangeToMidi1)
224+ {
225+ auto midi2CC = makeMidi2ControlChangeMessage (3 , 6 , 7 , ControllerValue { 0x70000000u });
226+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2CC });
227+ ASSERT_TRUE (result.has_value ());
228+ EXPECT_TRUE (isControlChangeMessage (*result));
229+ }
230+
231+ TEST (UMPChannelVoiceTests, Midi2ProgramChangeToMidi1)
232+ {
233+ auto midi2PC = makeMidi2ProgramChangeMessage (4 , 7 , 55 );
234+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2PC });
235+ ASSERT_TRUE (result.has_value ());
236+ EXPECT_TRUE (isProgramChangeMessage (*result));
237+ }
238+
239+ TEST (UMPChannelVoiceTests, Midi2ChannelPressureToMidi1)
240+ {
241+ auto midi2CP = makeMidi2ChannelPressureMessage (5 , 8 , ControllerValue { 0x60000000u });
242+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2CP });
243+ ASSERT_TRUE (result.has_value ());
244+ EXPECT_TRUE (isChannelPressureMessage (*result));
245+ }
246+
247+ TEST (UMPChannelVoiceTests, Midi2PitchBendToMidi1)
248+ {
249+ auto midi2PB = makeMidi2PitchBendMessage (6 , 9 , PitchBend { 0x80000000u });
250+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2PB });
251+ ASSERT_TRUE (result.has_value ());
252+ EXPECT_TRUE (isChannelPitchBendMessage (*result));
253+ }
254+
255+ TEST (UMPChannelVoiceTests, Midi2NoteOnZeroVelocityToMidi1)
256+ {
257+ auto midi2NoteOn = makeMidi2NoteOnMessage (2 , 3 , 60 , Velocity { uint16_t { 0 } });
258+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2NoteOn });
259+ ASSERT_TRUE (result.has_value ());
260+ EXPECT_TRUE (isNoteOnMessage (*result));
261+ EXPECT_EQ (getNoteVelocity (*result).asUInt7 (), 1 );
262+ }
263+
264+ TEST (UMPChannelVoiceTests, Midi2WithAttributeNotTranslatable)
265+ {
266+ auto midi2NoteOn = makeMidi2NoteOnMessage (2 , 3 , 60 , Velocity { uint16_t { 0x8000 } }, Pitch7_9 { 61 .5f });
267+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2NoteOn });
268+ EXPECT_FALSE (result.has_value ());
269+ }
270+
271+ TEST (UMPChannelVoiceTests, Midi1SpecialCCNotTranslated)
272+ {
273+ auto midi1BankSelect = makeMidi1ControlChangeMessage (3 , 7 , ControlChange::bankSelectMsb, ControllerValue { uint7_t { 1 } });
274+ auto result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1BankSelect });
275+ EXPECT_FALSE (result.has_value ());
276+
277+ auto midi1RpnLsb = makeMidi1ControlChangeMessage (3 , 7 , ControlChange::rpnLsb, ControllerValue { uint7_t { 1 } });
278+ result = asMidi2ChannelVoiceMessage (Midi1ChannelVoiceMessageView { midi1RpnLsb });
279+ EXPECT_FALSE (result.has_value ());
280+ }
281+
282+ TEST (UMPChannelVoiceTests, Midi2SpecialCCNotTranslated)
283+ {
284+ auto midi2BankSelect = makeMidi2ControlChangeMessage (3 , 7 , ControlChange::bankSelectMsb, ControllerValue { 0x80000000u });
285+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2BankSelect });
286+ EXPECT_FALSE (result.has_value ());
287+
288+ auto midi2RpnMsb = makeMidi2ControlChangeMessage (3 , 7 , ControlChange::rpnMsb, ControllerValue { 0x80000000u });
289+ result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { midi2RpnMsb });
290+ EXPECT_FALSE (result.has_value ());
291+ }
292+
293+ TEST (UMPChannelVoiceTests, Midi2ProgramChangeWithBankSelectNotTranslated)
294+ {
295+ auto packet = makeMidi2ProgramChangeMessage (4 , 7 , 55 );
296+ packet.setByte (3 , packet.getByte (3 ) | 0x01 );
297+ auto result = asMidi1ChannelVoiceMessage (Midi2ChannelVoiceMessageView { packet });
298+ EXPECT_FALSE (result.has_value ());
299+ }
300+
301+ TEST (UMPChannelVoiceTests, GetProgramValueInvalid)
302+ {
303+ UniversalPacket invalidPacket { 0x10000000u };
304+ EXPECT_EQ (getProgramValue (invalidPacket), 0xff );
305+ }
306+
307+ TEST (UMPChannelVoiceTests, GetNotePitchOnMidi1)
308+ {
309+ auto midi1NoteOn = makeMidi1NoteOnMessage (2 , 3 , 60 , Velocity { uint7_t { 100 } });
310+ EXPECT_EQ (getNotePitch (midi1NoteOn), Pitch7_9 { NoteNumber (60 ) });
311+ }
312+
313+ TEST (UMPChannelVoiceTests, GetNoteVelocityOnMidi1NoteOn)
314+ {
315+ auto midi1NoteOn = makeMidi1NoteOnMessage (2 , 3 , 60 , Velocity { uint7_t { 100 } });
316+ EXPECT_EQ (getNoteVelocity (midi1NoteOn), Velocity { uint7_t { 100 } });
317+ }
318+
319+ TEST (UMPChannelVoiceTests, PerNoteMessages)
320+ {
321+ auto perNotePB = makePerNotePitchBendMessage (5 , 6 , 72 , PitchBend { 0x80001000u });
322+ EXPECT_TRUE (isPerNotePitchBendMessage (perNotePB));
323+
324+ auto regPerNoteCC = makeRegisteredPerNoteControllerMessage (3 , 4 , 60 , 1 , ControllerValue { 0x50000000u });
325+ EXPECT_TRUE (isRegisteredPerNoteControllerMessage (regPerNoteCC));
326+ EXPECT_EQ (getPerNoteControllerIndex (regPerNoteCC), 1 );
327+
328+ auto assPerNoteCC = makeAssignablePerNoteControllerMessage (7 , 8 , 64 , 5 , ControllerValue { 0x60000000u });
329+ EXPECT_TRUE (isAssignablePerNoteControllerMessage (assPerNoteCC));
330+ EXPECT_EQ (getPerNoteControllerIndex (assPerNoteCC), 5 );
331+ }
332+
333+ TEST (UMPChannelVoiceTests, RegisteredAndAssignableControllers)
334+ {
335+ auto regCC = makeRegisteredControllerMessage (2 , 3 , 0 , 5 , ControllerValue { 0x12345678u });
336+ EXPECT_TRUE (isRegisteredControllerMessage (regCC));
337+
338+ auto assCC = makeAssignableControllerMessage (4 , 5 , 1 , 7 , ControllerValue { 0x87654321u });
339+ EXPECT_TRUE (isAssignableControllerMessage (assCC));
340+ }
341+
342+ TEST (UMPChannelVoiceTests, PitchBendSensitivity)
343+ {
344+ auto pbSens = makeRegisteredControllerMessage (1 , 2 , 0 , RegisteredParameterNumber::pitchBendSensitivity, ControllerValue { 0x02000000u });
345+ EXPECT_TRUE (isPitchBendSensitivityMessage (pbSens));
346+ EXPECT_EQ (getPitchBendSensitivityValue (pbSens), PitchBendSensitivity { 0x02000000u });
347+ }
348+
349+ TEST (UMPChannelVoiceTests, GetMidi2NoteAttribute)
350+ {
351+ auto noteOn = makeMidi2NoteOnMessage (2 , 3 , 60 , Velocity { uint16_t { 0x8000 } }, Pitch7_9 { 61 .5f });
352+ EXPECT_EQ (getMidi2NoteAttribute (noteOn), NoteAttribute::pitch_7_9);
353+
354+ auto noteOnNoAttr = makeMidi2NoteOnMessage (2 , 3 , 60 , Velocity { uint16_t { 0x8000 } });
355+ EXPECT_EQ (getMidi2NoteAttribute (noteOnNoAttr), NoteAttribute::none);
356+ }
0 commit comments