| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "media/midi/usb_midi_input_stream.h" |
| |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/strings/stringprintf.h" |
| #include "base/time/time.h" |
| #include "media/midi/usb_midi_device.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| using base::TimeTicks; |
| |
| namespace midi { |
| |
| namespace { |
| |
| class TestUsbMidiDevice : public UsbMidiDevice { |
| public: |
| TestUsbMidiDevice() = default; |
| |
| TestUsbMidiDevice(const TestUsbMidiDevice&) = delete; |
| TestUsbMidiDevice& operator=(const TestUsbMidiDevice&) = delete; |
| |
| ~TestUsbMidiDevice() override = default; |
| std::vector<uint8_t> GetDescriptors() override { |
| return std::vector<uint8_t>(); |
| } |
| std::string GetManufacturer() override { return std::string(); } |
| std::string GetProductName() override { return std::string(); } |
| std::string GetDeviceVersion() override { return std::string(); } |
| void Send(int endpoint_number, const std::vector<uint8_t>& data) override {} |
| }; |
| |
| class MockDelegate : public UsbMidiInputStream::Delegate { |
| public: |
| MockDelegate() = default; |
| |
| MockDelegate(const MockDelegate&) = delete; |
| MockDelegate& operator=(const MockDelegate&) = delete; |
| |
| ~MockDelegate() override = default; |
| void OnReceivedData(size_t jack_index, |
| const uint8_t* data, |
| size_t size, |
| base::TimeTicks time) override { |
| for (size_t i = 0; i < size; ++i) |
| received_data_ += base::StringPrintf("0x%02x ", data[i]); |
| received_data_ += "\n"; |
| } |
| |
| const std::string& received_data() const { return received_data_; } |
| |
| private: |
| std::string received_data_; |
| }; |
| |
| class UsbMidiInputStreamTest : public ::testing::Test { |
| public: |
| UsbMidiInputStreamTest(const UsbMidiInputStreamTest&) = delete; |
| UsbMidiInputStreamTest& operator=(const UsbMidiInputStreamTest&) = delete; |
| |
| protected: |
| UsbMidiInputStreamTest() { |
| stream_ = std::make_unique<UsbMidiInputStream>(&delegate_); |
| |
| stream_->Add(UsbMidiJack(&device1_, |
| 84, // jack_id |
| 4, // cable_number |
| 135)); // endpoint_address |
| stream_->Add(UsbMidiJack(&device2_, |
| 85, |
| 5, |
| 137)); |
| stream_->Add(UsbMidiJack(&device2_, |
| 84, |
| 4, |
| 135)); |
| stream_->Add(UsbMidiJack(&device1_, |
| 85, |
| 5, |
| 135)); |
| } |
| |
| TestUsbMidiDevice device1_; |
| TestUsbMidiDevice device2_; |
| MockDelegate delegate_; |
| std::unique_ptr<UsbMidiInputStream> stream_; |
| }; |
| |
| TEST_F(UsbMidiInputStreamTest, UnknownMessage) { |
| uint8_t data[] = { |
| 0x40, 0xff, 0xff, 0xff, 0x41, 0xff, 0xff, 0xff, |
| }; |
| |
| stream_->OnReceivedData(&device1_, 7, data, std::size(data), TimeTicks()); |
| EXPECT_EQ("", delegate_.received_data()); |
| } |
| |
| TEST_F(UsbMidiInputStreamTest, SystemCommonMessage) { |
| uint8_t data[] = { |
| 0x45, 0xf8, 0x00, 0x00, 0x42, 0xf3, 0x22, 0x00, 0x43, 0xf2, 0x33, 0x44, |
| }; |
| |
| stream_->OnReceivedData(&device1_, 7, data, std::size(data), TimeTicks()); |
| EXPECT_EQ("0xf8 \n" |
| "0xf3 0x22 \n" |
| "0xf2 0x33 0x44 \n", delegate_.received_data()); |
| } |
| |
| TEST_F(UsbMidiInputStreamTest, SystemExclusiveMessage) { |
| uint8_t data[] = { |
| 0x44, 0xf0, 0x11, 0x22, 0x45, 0xf7, 0x00, 0x00, |
| 0x46, 0xf0, 0xf7, 0x00, 0x47, 0xf0, 0x33, 0xf7, |
| }; |
| |
| stream_->OnReceivedData(&device1_, 7, data, std::size(data), TimeTicks()); |
| EXPECT_EQ("0xf0 0x11 0x22 \n" |
| "0xf7 \n" |
| "0xf0 0xf7 \n" |
| "0xf0 0x33 0xf7 \n", delegate_.received_data()); |
| } |
| |
| TEST_F(UsbMidiInputStreamTest, ChannelMessage) { |
| uint8_t data[] = { |
| 0x48, 0x80, 0x11, 0x22, 0x49, 0x90, 0x33, 0x44, 0x4a, 0xa0, |
| 0x55, 0x66, 0x4b, 0xb0, 0x77, 0x88, 0x4c, 0xc0, 0x99, 0x00, |
| 0x4d, 0xd0, 0xaa, 0x00, 0x4e, 0xe0, 0xbb, 0xcc, |
| }; |
| |
| stream_->OnReceivedData(&device1_, 7, data, std::size(data), TimeTicks()); |
| EXPECT_EQ("0x80 0x11 0x22 \n" |
| "0x90 0x33 0x44 \n" |
| "0xa0 0x55 0x66 \n" |
| "0xb0 0x77 0x88 \n" |
| "0xc0 0x99 \n" |
| "0xd0 0xaa \n" |
| "0xe0 0xbb 0xcc \n", delegate_.received_data()); |
| } |
| |
| TEST_F(UsbMidiInputStreamTest, SingleByteMessage) { |
| uint8_t data[] = { |
| 0x4f, 0xf8, 0x00, 0x00, |
| }; |
| |
| stream_->OnReceivedData(&device1_, 7, data, std::size(data), TimeTicks()); |
| EXPECT_EQ("0xf8 \n", delegate_.received_data()); |
| } |
| |
| TEST_F(UsbMidiInputStreamTest, DispatchForMultipleCables) { |
| uint8_t data[] = { |
| 0x4f, 0xf8, 0x00, 0x00, 0x5f, 0xfa, 0x00, 0x00, 0x6f, 0xfb, 0x00, 0x00, |
| }; |
| |
| stream_->OnReceivedData(&device1_, 7, data, std::size(data), TimeTicks()); |
| EXPECT_EQ("0xf8 \n0xfa \n", delegate_.received_data()); |
| } |
| |
| TEST_F(UsbMidiInputStreamTest, DispatchForDevice2) { |
| uint8_t data[] = {0x4f, 0xf8, 0x00, 0x00}; |
| |
| stream_->OnReceivedData(&device2_, 7, data, std::size(data), TimeTicks()); |
| EXPECT_EQ("0xf8 \n", delegate_.received_data()); |
| } |
| |
| } // namespace |
| |
| } // namespace midi |