blob: 08f1a0bf7487ab25e26b72fa135bbe53fd2441ff [file] [log] [blame]
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +00001// 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
9namespace media {
10namespace {
11
12const uint8 kGMOn[] = { 0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7 };
13const uint8 kGSOn[] = {
14 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7,
15};
16const uint8 kNoteOn[] = { 0x90, 0x3c, 0x7f };
17const uint8 kNoteOnWithRunningStatus[] = {
18 0x90, 0x3c, 0x7f, 0x3c, 0x7f, 0x3c, 0x7f,
19};
20const uint8 kChannelPressure[] = { 0xd0, 0x01 };
21const uint8 kChannelPressureWithRunningStatus[] = {
22 0xd0, 0x01, 0x01, 0x01,
23};
24const uint8 kTimingClock[] = { 0xf8 };
toyoshim73c3f412015-02-22 21:18:09 -080025const uint8 kMTCFrame[] = { 0xf1, 0x00 };
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000026const uint8 kBrokenData1[] = { 0x90 };
27const uint8 kBrokenData2[] = { 0xf7 };
28const uint8 kBrokenData3[] = { 0xf2, 0x00 };
29const uint8 kDataByte0[] = { 0x00 };
30
31template <typename T, size_t N>
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000032void Add(MidiMessageQueue* queue, const T(&array)[N]) {
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000033 queue->Add(array, N);
34}
35
36template <typename T, size_t N>
37::testing::AssertionResult ExpectEqualSequence(
38 const char* expr1, const char* expr2,
39 const T(&expected)[N], const std::vector<T>& actual) {
40 if (actual.size() != N) {
41 return ::testing::AssertionFailure()
42 << "expected: " << ::testing::PrintToString(expected)
43 << ", actual: " << ::testing::PrintToString(actual);
44 }
45 for (size_t i = 0; i < N; ++i) {
46 if (expected[i] != actual[i]) {
47 return ::testing::AssertionFailure()
48 << "expected: " << ::testing::PrintToString(expected)
49 << ", actual: " << ::testing::PrintToString(actual);
50 }
51 }
52 return ::testing::AssertionSuccess();
53}
54
55#define EXPECT_MESSAGE(expected, actual) \
56 EXPECT_PRED_FORMAT2(ExpectEqualSequence, expected, actual)
57
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000058TEST(MidiMessageQueueTest, EmptyData) {
59 MidiMessageQueue queue(false);
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000060 std::vector<uint8> message;
61 queue.Get(&message);
62 EXPECT_TRUE(message.empty());
63}
64
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000065TEST(MidiMessageQueueTest, RunningStatusDisabled) {
66 MidiMessageQueue queue(false);
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +000067 Add(&queue, kGMOn);
68 Add(&queue, kBrokenData1);
69 Add(&queue, kNoteOnWithRunningStatus);
70 Add(&queue, kBrokenData2);
71 Add(&queue, kChannelPressureWithRunningStatus);
72 Add(&queue, kBrokenData3);
73 Add(&queue, kNoteOn);
74 Add(&queue, kBrokenData1);
75 Add(&queue, kGSOn);
76 Add(&queue, kBrokenData2);
77 Add(&queue, kTimingClock);
78 Add(&queue, kBrokenData3);
79
80 std::vector<uint8> message;
81 queue.Get(&message);
82 EXPECT_MESSAGE(kGMOn, message);
83 queue.Get(&message);
84 EXPECT_MESSAGE(kNoteOn, message) << "Running status should be ignored";
85 queue.Get(&message);
86 EXPECT_MESSAGE(kChannelPressure, message)
87 << "Running status should be ignored";
88 queue.Get(&message);
89 EXPECT_MESSAGE(kNoteOn, message);
90 queue.Get(&message);
91 EXPECT_MESSAGE(kGSOn, message);
92 queue.Get(&message);
93 EXPECT_MESSAGE(kTimingClock, message);
94 queue.Get(&message);
95 EXPECT_TRUE(message.empty());
96}
97
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +000098TEST(MidiMessageQueueTest, RunningStatusEnabled) {
99 MidiMessageQueue queue(true);
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +0000100 Add(&queue, kGMOn);
101 Add(&queue, kBrokenData1);
102 Add(&queue, kNoteOnWithRunningStatus);
103 Add(&queue, kBrokenData2);
104 Add(&queue, kChannelPressureWithRunningStatus);
105 Add(&queue, kBrokenData3);
106 Add(&queue, kNoteOn);
107 Add(&queue, kBrokenData1);
108 Add(&queue, kGSOn);
109 Add(&queue, kBrokenData2);
110 Add(&queue, kTimingClock);
111 Add(&queue, kDataByte0);
112
113 std::vector<uint8> message;
114 queue.Get(&message);
115 EXPECT_MESSAGE(kGMOn, message);
116 queue.Get(&message);
117 EXPECT_MESSAGE(kNoteOn, message);
118 queue.Get(&message);
119 EXPECT_MESSAGE(kNoteOn, message)
120 << "Running status should be converted into a canonical MIDI message";
121 queue.Get(&message);
122 EXPECT_MESSAGE(kNoteOn, message)
123 << "Running status should be converted into a canonical MIDI message";
124 queue.Get(&message);
125 EXPECT_MESSAGE(kChannelPressure, message);
126 queue.Get(&message);
127 EXPECT_MESSAGE(kChannelPressure, message)
128 << "Running status should be converted into a canonical MIDI message";
129 queue.Get(&message);
130 EXPECT_MESSAGE(kChannelPressure, message)
131 << "Running status should be converted into a canonical MIDI message";
132 queue.Get(&message);
133 EXPECT_MESSAGE(kNoteOn, message);
134 queue.Get(&message);
135 EXPECT_MESSAGE(kGSOn, message);
136 queue.Get(&message);
137 EXPECT_MESSAGE(kTimingClock, message);
138 queue.Get(&message);
139 EXPECT_TRUE(message.empty())
140 << "Running status must not be applied to real time messages";
141}
142
toyoshim@chromium.orgc82e66e2014-02-04 07:05:47 +0000143TEST(MidiMessageQueueTest, RunningStatusEnabledWithRealTimeEvent) {
144 MidiMessageQueue queue(true);
toyoshim73c3f412015-02-22 21:18:09 -0800145 const uint8 kNoteOnWithRunningStatusWithTimingClock[] = {
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +0000146 0x90, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8, 0x3c, 0xf8,
147 0x7f,
148 };
toyoshim73c3f412015-02-22 21:18:09 -0800149 Add(&queue, kNoteOnWithRunningStatusWithTimingClock);
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +0000150 std::vector<uint8> message;
151 queue.Get(&message);
152 EXPECT_MESSAGE(kTimingClock, message);
153 queue.Get(&message);
154 EXPECT_MESSAGE(kTimingClock, message);
155 queue.Get(&message);
156 EXPECT_MESSAGE(kNoteOn, message);
157 queue.Get(&message);
158 EXPECT_MESSAGE(kTimingClock, message);
159 queue.Get(&message);
160 EXPECT_MESSAGE(kTimingClock, message);
161 queue.Get(&message);
162 EXPECT_MESSAGE(kNoteOn, message);
163 queue.Get(&message);
164 EXPECT_MESSAGE(kTimingClock, message);
165 queue.Get(&message);
166 EXPECT_MESSAGE(kTimingClock, message);
167 queue.Get(&message);
168 EXPECT_MESSAGE(kNoteOn, message);
169 queue.Get(&message);
170 EXPECT_TRUE(message.empty());
171}
172
toyoshim73c3f412015-02-22 21:18:09 -0800173TEST(MidiMessageQueueTest, RunningStatusEnabledWithSystemCommonMessage) {
174 MidiMessageQueue queue(true);
175 const uint8 kNoteOnWithRunningStatusWithSystemCommonMessage[] = {
176 0x90, 0x3c, 0x7f, 0xf1, 0x00, 0x3c, 0x7f, 0xf8, 0x90, 0x3c, 0x7f,
177 };
178 Add(&queue, kNoteOnWithRunningStatusWithSystemCommonMessage);
179 std::vector<uint8> message;
180 queue.Get(&message);
181 EXPECT_MESSAGE(kNoteOn, message);
182 queue.Get(&message);
183 EXPECT_MESSAGE(kMTCFrame, message);
184 queue.Get(&message);
185 EXPECT_MESSAGE(kTimingClock, message) << "Running status should be reset";
186 queue.Get(&message);
187 EXPECT_MESSAGE(kNoteOn, message);
188 queue.Get(&message);
189 EXPECT_TRUE(message.empty());
190}
191
yukawa@chromium.org09ef89a2013-11-29 06:27:41 +0000192} // namespace
193} // namespace media