1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/midi/midi_message_queue.h" 6 7 #include "testing/gtest/include/gtest/gtest.h" 8 9 namespace media { 10 namespace { 11 12 const uint8 kGMOn[] = { 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7 }; 13 const uint8 kGSOn[] = { 14 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7, 15 }; 16 const uint8 kNoteOn[] = { 0x90, 0x3c, 0x7f }; 17 const uint8 kNoteOnWithRunningStatus[] = { 18 0x90, 0x3c, 0x7f, 0x3c, 0x7f, 0x3c, 0x7f, 19 }; 20 const uint8 kChannelPressure[] = { 0xd0, 0x01 }; 21 const uint8 kChannelPressureWithRunningStatus[] = { 22 0xd0, 0x01, 0x01, 0x01, 23 }; 24 const uint8 kTimingClock[] = { 0xf8 }; 25 const uint8 kBrokenData1[] = { 0x90 }; 26 const uint8 kBrokenData2[] = { 0xf7 }; 27 const uint8 kBrokenData3[] = { 0xf2, 0x00 }; 28 const uint8 kDataByte0[] = { 0x00 }; 29 30 template <typename T, size_t N> 31 void Add(MidiMessageQueue* queue, const T(&array)[N]) { 32 queue->Add(array, N); 33 } 34 35 template <typename T, size_t N> 36 ::testing::AssertionResult ExpectEqualSequence( 37 const char* expr1, const char* expr2, 38 const T(&expected)[N], const std::vector<T>& actual) { 39 if (actual.size() != N) { 40 return ::testing::AssertionFailure() 41 << "expected: " << ::testing::PrintToString(expected) 42 << ", actual: " << ::testing::PrintToString(actual); 43 } 44 for (size_t i = 0; i < N; ++i) { 45 if (expected[i] != actual[i]) { 46 return ::testing::AssertionFailure() 47 << "expected: " << ::testing::PrintToString(expected) 48 << ", actual: " << ::testing::PrintToString(actual); 49 } 50 } 51 return ::testing::AssertionSuccess(); 52 } 53 54 #define EXPECT_MESSAGE(expected, actual) \ 55 EXPECT_PRED_FORMAT2(ExpectEqualSequence, expected, actual) 56 57 TEST(MidiMessageQueueTest, EmptyData) { 58 MidiMessageQueue queue(false); 59 std::vector<uint8> message; 60 queue.Get(&message); 61 EXPECT_TRUE(message.empty()); 62 } 63 64 TEST(MidiMessageQueueTest, RunningStatusDisabled) { 65 MidiMessageQueue queue(false); 66 Add(&queue, kGMOn); 67 Add(&queue, kBrokenData1); 68 Add(&queue, kNoteOnWithRunningStatus); 69 Add(&queue, kBrokenData2); 70 Add(&queue, kChannelPressureWithRunningStatus); 71 Add(&queue, kBrokenData3); 72 Add(&queue, kNoteOn); 73 Add(&queue, kBrokenData1); 74 Add(&queue, kGSOn); 75 Add(&queue, kBrokenData2); 76 Add(&queue, kTimingClock); 77 Add(&queue, kBrokenData3); 78 79 std::vector<uint8> message; 80 queue.Get(&message); 81 EXPECT_MESSAGE(kGMOn, message); 82 queue.Get(&message); 83 EXPECT_MESSAGE(kNoteOn, message) << "Running status should be ignored"; 84 queue.Get(&message); 85 EXPECT_MESSAGE(kChannelPressure, message) 86 << "Running status should be ignored"; 87 queue.Get(&message); 88 EXPECT_MESSAGE(kNoteOn, message); 89 queue.Get(&message); 90 EXPECT_MESSAGE(kGSOn, message); 91 queue.Get(&message); 92 EXPECT_MESSAGE(kTimingClock, message); 93 queue.Get(&message); 94 EXPECT_TRUE(message.empty()); 95 } 96 97 TEST(MidiMessageQueueTest, RunningStatusEnabled) { 98 MidiMessageQueue queue(true); 99 Add(&queue, kGMOn); 100 Add(&queue, kBrokenData1); 101 Add(&queue, kNoteOnWithRunningStatus); 102 Add(&queue, kBrokenData2); 103 Add(&queue, kChannelPressureWithRunningStatus); 104 Add(&queue, kBrokenData3); 105 Add(&queue, kNoteOn); 106 Add(&queue, kBrokenData1); 107 Add(&queue, kGSOn); 108 Add(&queue, kBrokenData2); 109 Add(&queue, kTimingClock); 110 Add(&queue, kDataByte0); 111 112 std::vector<uint8> message; 113 queue.Get(&message); 114 EXPECT_MESSAGE(kGMOn, message); 115 queue.Get(&message); 116 EXPECT_MESSAGE(kNoteOn, message); 117 queue.Get(&message); 118 EXPECT_MESSAGE(kNoteOn, message) 119 << "Running status should be converted into a canonical MIDI message"; 120 queue.Get(&message); 121 EXPECT_MESSAGE(kNoteOn, message) 122 << "Running status should be converted into a canonical MIDI message"; 123 queue.Get(&message); 124 EXPECT_MESSAGE(kChannelPressure, message); 125 queue.Get(&message); 126 EXPECT_MESSAGE(kChannelPressure, message) 127 << "Running status should be converted into a canonical MIDI message"; 128 queue.Get(&message); 129 EXPECT_MESSAGE(kChannelPressure, message) 130 << "Running status should be converted into a canonical MIDI message"; 131 queue.Get(&message); 132 EXPECT_MESSAGE(kNoteOn, message); 133 queue.Get(&message); 134 EXPECT_MESSAGE(kGSOn, message); 135 queue.Get(&message); 136 EXPECT_MESSAGE(kTimingClock, message); 137 queue.Get(&message); 138 EXPECT_TRUE(message.empty()) 139 << "Running status must not be applied to real time messages"; 140 } 141 142 TEST(MidiMessageQueueTest, RunningStatusEnabledWithRealTimeEvent) { 143 MidiMessageQueue queue(true); 144 const uint8 kNoteOnWithRunningStatusWithkTimingClock[] = { 145 0x90, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8, 0x3c, 0xf8, 146 0x7f, 147 }; 148 Add(&queue, kNoteOnWithRunningStatusWithkTimingClock); 149 std::vector<uint8> message; 150 queue.Get(&message); 151 EXPECT_MESSAGE(kTimingClock, message); 152 queue.Get(&message); 153 EXPECT_MESSAGE(kTimingClock, message); 154 queue.Get(&message); 155 EXPECT_MESSAGE(kNoteOn, message); 156 queue.Get(&message); 157 EXPECT_MESSAGE(kTimingClock, message); 158 queue.Get(&message); 159 EXPECT_MESSAGE(kTimingClock, message); 160 queue.Get(&message); 161 EXPECT_MESSAGE(kNoteOn, message); 162 queue.Get(&message); 163 EXPECT_MESSAGE(kTimingClock, message); 164 queue.Get(&message); 165 EXPECT_MESSAGE(kTimingClock, message); 166 queue.Get(&message); 167 EXPECT_MESSAGE(kNoteOn, message); 168 queue.Get(&message); 169 EXPECT_TRUE(message.empty()); 170 } 171 172 } // namespace 173 } // namespace media 174