blob: 74539f3ac8ddf79a0f16d3c6c7d81c44c89559da [file] [log] [blame]
toyoshimbb2750c2016-10-20 05:13:24 -07001// 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/message_util.h"
6
7#include <stdint.h>
8
Lei Zhang21a44532021-05-26 19:26:48 +00009#include "base/cxx17_backports.h"
toyoshimbb2750c2016-10-20 05:13:24 -070010#include "testing/gtest/include/gtest/gtest.h"
11
12namespace midi {
13namespace {
14
15const uint8_t kGMOn[] = {0xf0, 0x7e, 0x7f, 0x09, 0x01, 0xf7};
16const uint8_t kGSOn[] = {
17 0xf0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41, 0xf7,
18};
19const uint8_t kNoteOn[] = {0x90, 0x3c, 0x7f};
20const uint8_t kNoteOnWithRunningStatus[] = {
21 0x90, 0x3c, 0x7f, 0x3c, 0x7f, 0x3c, 0x7f,
22};
23const uint8_t kNoteOnWithRealTimeClock[] = {
24 0x90, 0xf8, 0x3c, 0x7f, 0x90, 0xf8, 0x3c, 0xf8, 0x7f, 0xf8,
25};
26const uint8_t kGMOnWithRealTimeClock[] = {
27 0xf0, 0xf8, 0x7e, 0x7f, 0x09, 0x01, 0xf8, 0xf7,
28};
29const uint8_t kSystemCommonMessageReserved1[] = {0xf4};
30const uint8_t kSystemCommonMessageReserved2[] = {0xf5};
31const uint8_t kSystemCommonMessageTuneRequest[] = {0xf6};
32const uint8_t kChannelPressure[] = {0xd0, 0x01};
33const uint8_t kChannelPressureWithRunningStatus[] = {0xd0, 0x01, 0x01, 0x01};
34const uint8_t kTimingClock[] = {0xf8};
35const uint8_t kBrokenData1[] = {0x90};
36const uint8_t kBrokenData2[] = {0xf7};
37const uint8_t kBrokenData3[] = {0xf2, 0x00};
38const uint8_t kDataByte0[] = {0x00};
39
40template <typename T, size_t N>
41const std::vector<T> AsVector(const T (&data)[N]) {
42 std::vector<T> buffer;
43 buffer.insert(buffer.end(), data, data + N);
44 return buffer;
45}
46
47template <typename T, size_t N>
48void PushToVector(const T (&data)[N], std::vector<T>* buffer) {
49 buffer->insert(buffer->end(), data, data + N);
50}
51
52TEST(MidiMessageUtilTest, GetMessageLength) {
53 // Check basic functionarity
Avi Drissman2c637192018-12-25 20:26:39 +000054 EXPECT_EQ(base::size(kNoteOn), GetMessageLength(kNoteOn[0]));
55 EXPECT_EQ(base::size(kChannelPressure),
56 GetMessageLength(kChannelPressure[0]));
57 EXPECT_EQ(base::size(kTimingClock), GetMessageLength(kTimingClock[0]));
58 EXPECT_EQ(base::size(kSystemCommonMessageTuneRequest),
toyoshimbb2750c2016-10-20 05:13:24 -070059 GetMessageLength(kSystemCommonMessageTuneRequest[0]));
60
61 // SysEx message should be mapped to 0-length
62 EXPECT_EQ(0u, GetMessageLength(kGMOn[0]));
63
64 // Any reserved message should be mapped to 0-length
65 EXPECT_EQ(0u, GetMessageLength(kSystemCommonMessageReserved1[0]));
66 EXPECT_EQ(0u, GetMessageLength(kSystemCommonMessageReserved2[0]));
67
68 // Any data byte should be mapped to 0-length
69 EXPECT_EQ(0u, GetMessageLength(kGMOn[1]));
70 EXPECT_EQ(0u, GetMessageLength(kNoteOn[1]));
71 EXPECT_EQ(0u, GetMessageLength(kChannelPressure[1]));
72}
73
74TEST(MidiMessageUtilTest, IsValidWebMIDIData) {
75 // Test single event scenario
76 EXPECT_TRUE(IsValidWebMIDIData(AsVector(kGMOn)));
77 EXPECT_TRUE(IsValidWebMIDIData(AsVector(kGSOn)));
78 EXPECT_TRUE(IsValidWebMIDIData(AsVector(kNoteOn)));
79 EXPECT_TRUE(IsValidWebMIDIData(AsVector(kChannelPressure)));
80 EXPECT_TRUE(IsValidWebMIDIData(AsVector(kTimingClock)));
81 EXPECT_FALSE(IsValidWebMIDIData(AsVector(kBrokenData1)));
82 EXPECT_FALSE(IsValidWebMIDIData(AsVector(kBrokenData2)));
83 EXPECT_FALSE(IsValidWebMIDIData(AsVector(kBrokenData3)));
84 EXPECT_FALSE(IsValidWebMIDIData(AsVector(kDataByte0)));
85
86 // MIDI running status should be disallowed
87 EXPECT_FALSE(IsValidWebMIDIData(AsVector(kNoteOnWithRunningStatus)));
88 EXPECT_FALSE(IsValidWebMIDIData(AsVector(kChannelPressureWithRunningStatus)));
89
90 // Multiple messages are allowed as long as each of them is complete.
91 {
92 std::vector<uint8_t> buffer;
93 PushToVector(kGMOn, &buffer);
94 PushToVector(kNoteOn, &buffer);
95 PushToVector(kGSOn, &buffer);
96 PushToVector(kTimingClock, &buffer);
97 PushToVector(kNoteOn, &buffer);
98 EXPECT_TRUE(IsValidWebMIDIData(buffer));
99 PushToVector(kBrokenData1, &buffer);
100 EXPECT_FALSE(IsValidWebMIDIData(buffer));
101 }
102
103 // MIDI realtime message can be placed at any position.
104 EXPECT_TRUE(IsValidWebMIDIData(AsVector(kNoteOnWithRealTimeClock)));
105 EXPECT_TRUE(IsValidWebMIDIData(AsVector(kGMOnWithRealTimeClock)));
106}
107
108} // namespace
109} // namespace midi