PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

885 lines
30KB

  1. #include "unit-tests.h"
  2. #include "unit-tests_Settings.h"
  3. #include <src/MIDI.h>
  4. #include <test/mocks/test-mocks_SerialMock.h>
  5. BEGIN_MIDI_NAMESPACE
  6. END_MIDI_NAMESPACE
  7. // -----------------------------------------------------------------------------
  8. BEGIN_UNNAMED_NAMESPACE
  9. using namespace testing;
  10. USING_NAMESPACE_UNIT_TESTS;
  11. typedef test_mocks::SerialMock<32> SerialMock;
  12. typedef midi::SerialMIDI<SerialMock> Transport;
  13. typedef midi::MidiInterface<Transport> MidiInterface;
  14. typedef std::vector<uint8_t> Buffer;
  15. // --
  16. TEST(MidiOutput, sendInvalid)
  17. {
  18. SerialMock serial;
  19. Transport transport(serial);
  20. MidiInterface midi((Transport&)transport);
  21. midi.begin();
  22. midi.send(midi::NoteOn, 42, 42, 42); // Invalid channel > OFF
  23. EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
  24. midi.send(midi::InvalidType, 0, 0, 12); // Invalid type
  25. EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
  26. midi.send(midi::NoteOn, 12, 42, MIDI_CHANNEL_OMNI); // OMNI not allowed
  27. EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
  28. }
  29. TEST(MidiOutput, sendGenericSingle)
  30. {
  31. SerialMock serial;
  32. Transport transport(serial);
  33. MidiInterface midi((Transport&)transport);
  34. Buffer buffer;
  35. buffer.resize(3);
  36. midi.begin();
  37. midi.send(midi::NoteOn, 47, 42, 12);
  38. EXPECT_EQ(serial.mTxBuffer.getLength(), 3);
  39. serial.mTxBuffer.read(&buffer[0], 3);
  40. EXPECT_THAT(buffer, ElementsAreArray({0x9b, 47, 42}));
  41. }
  42. TEST(MidiOutput, sendGenericWithRunningStatus)
  43. {
  44. typedef VariableSettings<true, false> Settings;
  45. typedef midi::MidiInterface<Transport, Settings> RsMidiInterface;
  46. SerialMock serial;
  47. Transport transport(serial);
  48. RsMidiInterface midi((Transport&)transport);
  49. Buffer buffer;
  50. buffer.resize(5);
  51. midi.begin();
  52. EXPECT_EQ(RsMidiInterface::Settings::UseRunningStatus, true);
  53. EXPECT_EQ(serial.mTxBuffer.isEmpty(), true);
  54. midi.send(midi::NoteOn, 47, 42, 12);
  55. midi.send(midi::NoteOn, 42, 47, 12);
  56. EXPECT_EQ(serial.mTxBuffer.getLength(), 5);
  57. serial.mTxBuffer.read(&buffer[0], 5);
  58. EXPECT_THAT(buffer, ElementsAreArray({0x9b, 47, 42, 42, 47}));
  59. }
  60. TEST(MidiOutput, sendGenericWithoutRunningStatus)
  61. {
  62. typedef VariableSettings<false, true> Settings; // No running status
  63. typedef midi::MidiInterface<Transport, Settings> NoRsMidiInterface;
  64. SerialMock serial;
  65. Transport transport(serial);
  66. NoRsMidiInterface midi((Transport&)transport);
  67. Buffer buffer;
  68. buffer.resize(6);
  69. // Same status byte
  70. midi.begin();
  71. EXPECT_EQ(MidiInterface::Settings::UseRunningStatus, false);
  72. EXPECT_EQ(serial.mTxBuffer.isEmpty(), true);
  73. midi.send(midi::NoteOn, 47, 42, 12);
  74. midi.send(midi::NoteOn, 42, 47, 12);
  75. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  76. serial.mTxBuffer.read(&buffer[0], 6);
  77. EXPECT_THAT(buffer, ElementsAreArray({0x9b, 47, 42, 0x9b, 42, 47}));
  78. // Different status byte
  79. midi.begin();
  80. midi.send(midi::NoteOn, 47, 42, 12);
  81. midi.send(midi::NoteOff, 47, 42, 12);
  82. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  83. serial.mTxBuffer.read(&buffer[0], 6);
  84. EXPECT_THAT(buffer, ElementsAreArray({0x9b, 47, 42, 0x8b, 47, 42}));
  85. }
  86. TEST(MidiOutput, sendGenericBreakingRunningStatus)
  87. {
  88. SerialMock serial;
  89. Transport transport(serial);
  90. MidiInterface midi((Transport&)transport);
  91. Buffer buffer;
  92. buffer.resize(6);
  93. midi.begin();
  94. midi.send(midi::NoteOn, 47, 42, 12);
  95. midi.send(midi::NoteOff, 47, 42, 12);
  96. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  97. serial.mTxBuffer.read(&buffer[0], 6);
  98. EXPECT_THAT(buffer, ElementsAreArray({0x9b, 47, 42, 0x8b, 47, 42}));
  99. }
  100. TEST(MidiOutput, sendGenericRealTimeShortcut)
  101. {
  102. SerialMock serial;
  103. Transport transport(serial);
  104. MidiInterface midi((Transport&)transport);
  105. Buffer buffer;
  106. buffer.resize(6);
  107. midi.begin();
  108. midi.send(midi::Clock, 47, 42, 12);
  109. midi.send(midi::Start, 47, 42, 12);
  110. midi.send(midi::Continue, 47, 42, 12);
  111. midi.send(midi::Stop, 47, 42, 12);
  112. midi.send(midi::ActiveSensing, 47, 42, 12);
  113. midi.send(midi::SystemReset, 47, 42, 12);
  114. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  115. serial.mTxBuffer.read(&buffer[0], 6);
  116. EXPECT_THAT(buffer, ElementsAreArray({0xf8, 0xfa, 0xfb, 0xfc, 0xfe, 0xff}));
  117. }
  118. // --
  119. TEST(MidiOutput, sendNoteOn)
  120. {
  121. SerialMock serial;
  122. Transport transport(serial);
  123. MidiInterface midi((Transport&)transport);
  124. Buffer buffer;
  125. buffer.resize(6);
  126. midi.begin();
  127. midi.sendNoteOn(10, 11, 12);
  128. midi.sendNoteOn(12, 13, 4);
  129. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  130. serial.mTxBuffer.read(&buffer[0], 6);
  131. EXPECT_THAT(buffer, ElementsAreArray({0x9b, 10, 11, 0x93, 12, 13}));
  132. }
  133. TEST(MidiOutput, sendNoteOff)
  134. {
  135. SerialMock serial;
  136. Transport transport(serial);
  137. MidiInterface midi((Transport&)transport);
  138. Buffer buffer;
  139. buffer.resize(6);
  140. midi.begin();
  141. midi.sendNoteOff(10, 11, 12);
  142. midi.sendNoteOff(12, 13, 4);
  143. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  144. serial.mTxBuffer.read(&buffer[0], 6);
  145. EXPECT_THAT(buffer, ElementsAreArray({0x8b, 10, 11, 0x83, 12, 13}));
  146. }
  147. TEST(MidiOutput, sendProgramChange)
  148. {
  149. SerialMock serial;
  150. Transport transport(serial);
  151. MidiInterface midi((Transport&)transport);
  152. Buffer buffer;
  153. buffer.resize(4);
  154. midi.begin();
  155. midi.sendProgramChange(42, 12);
  156. midi.sendProgramChange(47, 4);
  157. EXPECT_EQ(serial.mTxBuffer.getLength(), 4);
  158. serial.mTxBuffer.read(&buffer[0], 4);
  159. EXPECT_THAT(buffer, ElementsAreArray({0xcb, 42, 0xc3, 47}));
  160. }
  161. TEST(MidiOutput, sendControlChange)
  162. {
  163. SerialMock serial;
  164. Transport transport(serial);
  165. MidiInterface midi((Transport&)transport);
  166. Buffer buffer;
  167. buffer.resize(6);
  168. midi.begin();
  169. midi.sendControlChange(42, 12, 12);
  170. midi.sendControlChange(47, 12, 4);
  171. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  172. serial.mTxBuffer.read(&buffer[0], 6);
  173. EXPECT_THAT(buffer, ElementsAreArray({0xbb, 42, 12, 0xb3, 47, 12}));
  174. }
  175. TEST(MidiOutput, sendPitchBend)
  176. {
  177. SerialMock serial;
  178. Transport transport(serial);
  179. MidiInterface midi((Transport&)transport);
  180. Buffer buffer;
  181. // Int signature - arbitrary values
  182. {
  183. buffer.clear();
  184. buffer.resize(9);
  185. midi.begin();
  186. midi.sendPitchBend(0, 12);
  187. midi.sendPitchBend(100, 4);
  188. midi.sendPitchBend(-100, 7);
  189. EXPECT_EQ(serial.mTxBuffer.getLength(), 9);
  190. serial.mTxBuffer.read(&buffer[0], 9);
  191. EXPECT_THAT(buffer, ElementsAreArray({0xeb, 0x00, 0x40,
  192. 0xe3, 0x64, 0x40,
  193. 0xe6, 0x1c, 0x3f}));
  194. }
  195. // Int signature - min/max
  196. {
  197. buffer.clear();
  198. buffer.resize(9);
  199. midi.begin();
  200. midi.sendPitchBend(0, 12);
  201. midi.sendPitchBend(MIDI_PITCHBEND_MAX, 4);
  202. midi.sendPitchBend(MIDI_PITCHBEND_MIN, 7);
  203. EXPECT_EQ(serial.mTxBuffer.getLength(), 9);
  204. serial.mTxBuffer.read(&buffer[0], 9);
  205. EXPECT_THAT(buffer, ElementsAreArray({0xeb, 0x00, 0x40,
  206. 0xe3, 0x7f, 0x7f,
  207. 0xe6, 0x00, 0x00}));
  208. }
  209. // Float signature
  210. {
  211. buffer.clear();
  212. buffer.resize(9);
  213. midi.begin();
  214. midi.sendPitchBend(0.0, 12);
  215. midi.sendPitchBend(1.0, 4);
  216. midi.sendPitchBend(-1.0, 7);
  217. EXPECT_EQ(serial.mTxBuffer.getLength(), 9);
  218. serial.mTxBuffer.read(&buffer[0], 9);
  219. EXPECT_THAT(buffer, ElementsAreArray({0xeb, 0x00, 0x40,
  220. 0xe3, 0x7f, 0x7f,
  221. 0xe6, 0x00, 0x00}));
  222. }
  223. }
  224. TEST(MidiOutput, sendPolyPressure)
  225. {
  226. // Note: sendPolyPressure is deprecated in favor of sendAfterTouch, which
  227. // now supports both mono and poly AfterTouch messages.
  228. // This test is kept for coverage until removal of sendPolyPressure.
  229. SerialMock serial;
  230. Transport transport(serial);
  231. MidiInterface midi((Transport&)transport);
  232. Buffer buffer;
  233. buffer.resize(6);
  234. midi.begin();
  235. midi.sendPolyPressure(42, 12, 12);
  236. midi.sendPolyPressure(47, 12, 4);
  237. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  238. serial.mTxBuffer.read(&buffer[0], 6);
  239. EXPECT_THAT(buffer, ElementsAreArray({0xab, 42, 12, 0xa3, 47, 12}));
  240. }
  241. TEST(MidiOutput, sendAfterTouchMono)
  242. {
  243. SerialMock serial;
  244. Transport transport(serial);
  245. MidiInterface midi((Transport&)transport);
  246. Buffer buffer;
  247. buffer.resize(4);
  248. midi.begin();
  249. midi.sendAfterTouch(42, 12);
  250. midi.sendAfterTouch(47, 4);
  251. EXPECT_EQ(serial.mTxBuffer.getLength(), 4);
  252. serial.mTxBuffer.read(&buffer[0], 4);
  253. EXPECT_THAT(buffer, ElementsAreArray({0xdb, 42, 0xd3, 47}));
  254. }
  255. TEST(MidiOutput, sendAfterTouchPoly)
  256. {
  257. SerialMock serial;
  258. Transport transport(serial);
  259. MidiInterface midi((Transport&)transport);
  260. Buffer buffer;
  261. buffer.resize(6);
  262. midi.begin();
  263. midi.sendAfterTouch(42, 12, 12);
  264. midi.sendAfterTouch(47, 12, 4);
  265. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  266. serial.mTxBuffer.read(&buffer[0], 6);
  267. EXPECT_THAT(buffer, ElementsAreArray({0xab, 42, 12, 0xa3, 47, 12}));
  268. }
  269. TEST(MidiOutput, sendSysEx)
  270. {
  271. typedef test_mocks::SerialMock<1024> LargeSerialMock;
  272. typedef midi::SerialMIDI<LargeSerialMock> LargeTransport;
  273. typedef midi::MidiInterface<LargeTransport> LargeMidiInterface;
  274. LargeSerialMock serial;
  275. LargeTransport transport(serial);
  276. LargeMidiInterface midi((LargeTransport&)transport);
  277. Buffer buffer;
  278. // Short frame
  279. {
  280. static const char* frame = "Hello, World!";
  281. static const int frameLength = strlen(frame);
  282. static const byte expected[] = {
  283. 0xf0,
  284. 'H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '!',
  285. 0xf7,
  286. };
  287. buffer.clear();
  288. buffer.resize(frameLength + 2);
  289. midi.begin();
  290. midi.sendSysEx(frameLength, reinterpret_cast<const byte*>(frame), false);
  291. EXPECT_EQ(serial.mTxBuffer.getLength(), frameLength + 2);
  292. serial.mTxBuffer.read(&buffer[0], frameLength + 2);
  293. EXPECT_THAT(buffer, ElementsAreArray(expected));
  294. }
  295. // Long frame
  296. {
  297. static const char* frame = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin maximus dui a massa maximus, a vestibulum mi venenatis. Cras sit amet ex id velit suscipit pharetra eget a turpis. Phasellus interdum metus ac sagittis cursus. Nam quis est at nisl ullamcorper egestas pulvinar eu erat. Duis a elit dignissim, vestibulum eros vel, tempus nisl. Aenean turpis nunc, cursus vel lacinia non, pharetra eget sapien. Duis condimentum, lacus at pulvinar tempor, leo libero volutpat nisl, eget porttitor lorem mi sed magna. Duis dictum, massa vel euismod interdum, lorem mi egestas elit, hendrerit tincidunt est arcu a libero. Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur vehicula magna libero, at rhoncus sem ornare a. In elementum, elit et congue pulvinar, massa velit commodo velit, non elementum purus ligula eget lacus. Donec efficitur nisi eu ultrices efficitur. Donec neque dui, ullamcorper id molestie quis, consequat sit amet ligula.";
  298. static const int frameLength = strlen(frame);
  299. static const byte expected[] = {
  300. 0xf0,
  301. 'L','o','r','e','m',' ','i','p','s','u','m',' ','d','o','l','o','r',' ','s','i','t',' ','a','m','e','t',',',' ',
  302. 'c','o','n','s','e','c','t','e','t','u','r',' ','a','d','i','p','i','s','c','i','n','g',' ','e','l','i','t','.',' ','P','r','o','i','n',' ','m','a','x','i','m','u','s',' ','d','u','i',' ','a',' ','m','a','s','s','a',' ','m','a','x','i','m','u','s',',',' ',
  303. 'a',' ','v','e','s','t','i','b','u','l','u','m',' ','m','i',' ','v','e','n','e','n','a','t','i','s','.',' ','C','r','a','s',' ','s','i','t',' ','a','m','e','t',' ','e','x',' ','i','d',' ','v','e','l','i','t',' ','s','u','s','c','i','p','i','t',' ','p','h','a','r','e','t','r','a',' ','e','g','e','t', ' ','a',' ','t','u','r','p','i','s','.',' ','P','h','a','s','e','l','l','u','s',' ','i','n','t','e','r','d','u','m',' ','m','e','t','u','s',' ','a','c',' ','s','a','g','i','t','t','i','s',' ','c','u','r','s','u','s','.',' ','N','a','m',' ','q','u','i','s',' ','e','s','t',' ','a','t',' ','n','i','s', 'l',' ','u','l','l','a','m','c','o','r','p','e','r',' ','e','g','e','s','t','a','s',' ','p','u','l','v','i','n','a','r',' ','e','u',' ','e','r','a','t','.',' ','D','u','i','s',' ','a',' ','e','l','i','t',' ','d','i','g','n','i','s','s','i','m',',',' ',
  304. 'v','e','s','t','i','b','u','l','u','m',' ','e','r','o','s',' ','v','e','l',',',' ',
  305. 't','e','m','p','u','s',' ','n','i','s','l','.',' ','A','e','n','e','a','n',' ','t','u','r','p','i','s',' ','n','u','n','c',',',' ',
  306. 'c','u','r','s','u','s',' ','v','e','l',' ','l','a','c','i','n','i','a',' ','n','o','n',',',' ',
  307. 'p','h','a','r','e','t','r','a',' ','e','g','e','t',' ','s','a','p','i','e','n','.',' ','D','u','i','s',' ','c','o','n','d','i','m','e','n','t','u','m',',',' ',
  308. 'l','a','c','u','s',' ','a','t',' ','p','u','l','v','i','n','a','r',' ','t','e','m','p','o','r',',',' ',
  309. 'l','e','o',' ','l','i','b','e','r','o',' ','v','o','l','u','t','p','a','t',' ','n','i','s','l',',',' ',
  310. 'e','g','e','t',' ','p','o','r','t','t','i','t','o','r',' ','l','o','r','e','m',' ','m','i',' ','s','e','d',' ','m','a','g','n','a','.',' ','D','u','i','s',' ','d','i','c','t','u','m',',',' ',
  311. 'm','a','s','s','a',' ','v','e','l',' ','e','u','i','s','m','o','d',' ','i','n','t','e','r','d','u','m',',',' ',
  312. 'l','o','r','e','m',' ','m','i',' ','e','g','e','s','t','a','s',' ','e','l','i','t',',',' ',
  313. 'h','e','n','d','r','e','r','i','t',' ','t','i','n','c','i','d','u','n','t',' ','e','s','t',' ','a','r','c','u',' ','a',' ','l','i','b','e','r','o','.',' ','I','n','t','e','r','d','u','m',' ','e','t',' ','m','a','l','e','s','u','a','d','a',' ','f','a','m','e','s',' ','a','c',' ','a','n','t','e',' ', 'i','p','s','u','m',' ','p','r','i','m','i','s',' ','i','n',' ','f','a','u','c','i','b','u','s','.',' ','C','u','r','a','b','i','t','u','r',' ','v','e','h','i','c','u','l','a',' ','m','a','g','n','a',' ','l','i','b','e','r','o',',',' ',
  314. 'a','t',' ','r','h','o','n','c','u','s',' ','s','e','m',' ','o','r','n','a','r','e',' ','a','.',' ','I','n',' ','e','l','e','m','e','n','t','u','m',',',' ',
  315. 'e','l','i','t',' ','e','t',' ','c','o','n','g','u','e',' ','p','u','l','v','i','n','a','r',',',' ',
  316. 'm','a','s','s','a',' ','v','e','l','i','t',' ','c','o','m','m','o','d','o',' ','v','e','l','i','t',',',' ',
  317. 'n','o','n',' ','e','l','e','m','e','n','t','u','m',' ','p','u','r','u','s',' ','l','i','g','u','l','a',' ','e','g','e','t',' ','l','a','c','u','s','.',' ','D','o','n','e','c',' ','e','f','f','i','c','i','t','u','r',' ','n','i','s','i',' ','e','u',' ','u','l','t','r','i','c','e','s',' ','e','f','f', 'i','c','i','t','u','r','.',' ','D','o','n','e','c',' ','n','e','q','u','e',' ','d','u','i',',',' ',
  318. 'u','l','l','a','m','c','o','r','p','e','r',' ','i','d',' ','m','o','l','e','s','t','i','e',' ','q','u','i','s',',',' ',
  319. 'c','o','n','s','e','q','u','a','t',' ','s','i','t',' ','a','m','e','t',' ','l','i','g','u','l','a','.',
  320. 0xf7,
  321. };
  322. buffer.clear();
  323. buffer.resize(frameLength + 2);
  324. midi.begin();
  325. midi.sendSysEx(frameLength, reinterpret_cast<const byte*>(frame), false);
  326. EXPECT_EQ(serial.mTxBuffer.getLength(), frameLength + 2);
  327. serial.mTxBuffer.read(&buffer[0], frameLength + 2);
  328. EXPECT_THAT(buffer, ElementsAreArray(expected));
  329. }
  330. // With boundaries included
  331. {
  332. static const byte frame[] = {
  333. 0xf0, 12, 17, 42, 47, 0xf7
  334. };
  335. buffer.clear();
  336. buffer.resize(6);
  337. midi.begin();
  338. midi.sendSysEx(6, frame, true);
  339. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  340. serial.mTxBuffer.read(&buffer[0], 6);
  341. EXPECT_THAT(buffer, ElementsAreArray(frame));
  342. }
  343. }
  344. TEST(MidiOutput, sendTimeCodeQuarterFrame)
  345. {
  346. SerialMock serial;
  347. Transport transport(serial);
  348. MidiInterface midi((Transport&)transport);
  349. Buffer buffer;
  350. // Separate Nibbles
  351. {
  352. buffer.clear();
  353. buffer.resize(4);
  354. midi.begin();
  355. midi.sendTimeCodeQuarterFrame(0x05, 0x0a);
  356. midi.sendTimeCodeQuarterFrame(0xff, 0xff);
  357. EXPECT_EQ(serial.mTxBuffer.getLength(), 4);
  358. serial.mTxBuffer.read(&buffer[0], 4);
  359. EXPECT_THAT(buffer, ElementsAreArray({0xf1, 0x5a,
  360. 0xf1, 0x7f}));
  361. }
  362. // Pre-encoded nibbles
  363. {
  364. buffer.clear();
  365. buffer.resize(4);
  366. midi.begin();
  367. midi.sendTimeCodeQuarterFrame(12);
  368. midi.sendTimeCodeQuarterFrame(42);
  369. EXPECT_EQ(serial.mTxBuffer.getLength(), 4);
  370. serial.mTxBuffer.read(&buffer[0], 4);
  371. EXPECT_THAT(buffer, ElementsAreArray({0xf1, 0x0c,
  372. 0xf1, 0x2a}));
  373. }
  374. }
  375. TEST(MidiOutput, sendSongPosition)
  376. {
  377. SerialMock serial;
  378. Transport transport(serial);
  379. MidiInterface midi((Transport&)transport);
  380. Buffer buffer;
  381. buffer.resize(6);
  382. midi.begin();
  383. midi.sendSongPosition(1234);
  384. midi.sendSongPosition(4321);
  385. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  386. serial.mTxBuffer.read(&buffer[0], 6);
  387. EXPECT_THAT(buffer, ElementsAreArray({0xf2, 0x52, 0x09,
  388. 0xf2, 0x61, 0x21}));
  389. }
  390. TEST(MidiOutput, sendSongSelect)
  391. {
  392. SerialMock serial;
  393. Transport transport(serial);
  394. MidiInterface midi((Transport&)transport);
  395. Buffer buffer;
  396. buffer.resize(4);
  397. midi.begin();
  398. midi.sendSongSelect(12);
  399. midi.sendSongSelect(42);
  400. EXPECT_EQ(serial.mTxBuffer.getLength(), 4);
  401. serial.mTxBuffer.read(&buffer[0], 4);
  402. EXPECT_THAT(buffer, ElementsAreArray({0xf3, 12, 0xf3, 42}));
  403. }
  404. TEST(MidiOutput, sendTuneRequest)
  405. {
  406. SerialMock serial;
  407. Transport transport(serial);
  408. MidiInterface midi((Transport&)transport);
  409. Buffer buffer;
  410. buffer.resize(1);
  411. midi.begin();
  412. midi.sendTuneRequest();
  413. EXPECT_EQ(serial.mTxBuffer.getLength(), 1);
  414. serial.mTxBuffer.read(&buffer[0], 1);
  415. EXPECT_THAT(buffer, ElementsAreArray({0xf6}));
  416. }
  417. TEST(MidiOutput, sendRealTime)
  418. {
  419. SerialMock serial;
  420. Transport transport(serial);
  421. MidiInterface midi((Transport&)transport);
  422. Buffer buffer;
  423. // Test valid RealTime messages
  424. {
  425. buffer.clear();
  426. buffer.resize(6);
  427. midi.begin();
  428. midi.sendRealTime(midi::Clock);
  429. midi.sendRealTime(midi::Start);
  430. midi.sendRealTime(midi::Continue);
  431. midi.sendRealTime(midi::Stop);
  432. midi.sendRealTime(midi::ActiveSensing);
  433. midi.sendRealTime(midi::SystemReset);
  434. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  435. serial.mTxBuffer.read(&buffer[0], 6);
  436. EXPECT_THAT(buffer, ElementsAreArray({
  437. 0xf8, 0xfa, 0xfb, 0xfc, 0xfe, 0xff
  438. }));
  439. }
  440. // Test invalid messages
  441. {
  442. midi.begin();
  443. midi.sendRealTime(midi::InvalidType);
  444. midi.sendRealTime(midi::NoteOff);
  445. midi.sendRealTime(midi::NoteOn);
  446. midi.sendRealTime(midi::AfterTouchPoly);
  447. midi.sendRealTime(midi::ControlChange);
  448. midi.sendRealTime(midi::ProgramChange);
  449. midi.sendRealTime(midi::AfterTouchChannel);
  450. midi.sendRealTime(midi::PitchBend);
  451. midi.sendRealTime(midi::SystemExclusive);
  452. midi.sendRealTime(midi::TimeCodeQuarterFrame);
  453. midi.sendRealTime(midi::SongPosition);
  454. midi.sendRealTime(midi::SongSelect);
  455. midi.sendRealTime(midi::TuneRequest);
  456. EXPECT_EQ(serial.mTxBuffer.getLength(), 0);
  457. }
  458. }
  459. TEST(MidiOutput, RPN)
  460. {
  461. typedef VariableSettings<true, true> Settings;
  462. typedef midi::MidiInterface<Transport, Settings> RsMidiInterface;
  463. SerialMock serial;
  464. Transport transport(serial);
  465. RsMidiInterface midi((Transport&)transport);
  466. Buffer buffer;
  467. // 14-bit Value Single Frame
  468. {
  469. buffer.clear();
  470. buffer.resize(13);
  471. midi.begin();
  472. midi.beginRpn(1242, 12);
  473. midi.sendRpnValue(12345, 12);
  474. midi.endRpn(12);
  475. EXPECT_EQ(serial.mTxBuffer.getLength(), 13);
  476. serial.mTxBuffer.read(&buffer[0], 13);
  477. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  478. 0x64, 0x5a,
  479. 0x65, 0x09,
  480. 0x06, 0x60,
  481. 0x26, 0x39,
  482. 0x64, 0x7f,
  483. 0x65, 0x7f}));
  484. }
  485. // MSB/LSB Single Frame
  486. {
  487. buffer.clear();
  488. buffer.resize(13);
  489. midi.begin();
  490. midi.beginRpn(1242, 12);
  491. midi.sendRpnValue(12, 42, 12);
  492. midi.endRpn(12);
  493. EXPECT_EQ(serial.mTxBuffer.getLength(), 13);
  494. serial.mTxBuffer.read(&buffer[0], 13);
  495. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  496. 0x64, 0x5a,
  497. 0x65, 0x09,
  498. 0x06, 0x0c,
  499. 0x26, 0x2a,
  500. 0x64, 0x7f,
  501. 0x65, 0x7f}));
  502. }
  503. // Increment Single Frame
  504. {
  505. buffer.clear();
  506. buffer.resize(11);
  507. midi.begin();
  508. midi.beginRpn(1242, 12);
  509. midi.sendRpnIncrement(42, 12);
  510. midi.endRpn(12);
  511. EXPECT_EQ(serial.mTxBuffer.getLength(), 11);
  512. serial.mTxBuffer.read(&buffer[0], 11);
  513. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  514. 0x64, 0x5a,
  515. 0x65, 0x09,
  516. 0x60, 0x2a,
  517. 0x64, 0x7f,
  518. 0x65, 0x7f}));
  519. }
  520. // Decrement Single Frame
  521. {
  522. buffer.clear();
  523. buffer.resize(11);
  524. midi.begin();
  525. midi.beginRpn(1242, 12);
  526. midi.sendRpnDecrement(42, 12);
  527. midi.endRpn(12);
  528. EXPECT_EQ(serial.mTxBuffer.getLength(), 11);
  529. serial.mTxBuffer.read(&buffer[0], 11);
  530. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  531. 0x64, 0x5a,
  532. 0x65, 0x09,
  533. 0x61, 0x2a,
  534. 0x64, 0x7f,
  535. 0x65, 0x7f}));
  536. }
  537. // Multi Frame
  538. {
  539. buffer.clear();
  540. buffer.resize(21);
  541. midi.begin();
  542. midi.beginRpn(1242, 12);
  543. midi.sendRpnValue(12345, 12);
  544. midi.sendRpnValue(12, 42, 12);
  545. midi.sendRpnIncrement(42, 12);
  546. midi.sendRpnDecrement(42, 12);
  547. midi.endRpn(12);
  548. EXPECT_EQ(serial.mTxBuffer.getLength(), 21);
  549. serial.mTxBuffer.read(&buffer[0], 21);
  550. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  551. 0x64, 0x5a,
  552. 0x65, 0x09,
  553. 0x06, 0x60,
  554. 0x26, 0x39,
  555. 0x06, 0x0c,
  556. 0x26, 0x2a,
  557. 0x60, 0x2a,
  558. 0x61, 0x2a,
  559. 0x64, 0x7f,
  560. 0x65, 0x7f}));
  561. }
  562. }
  563. TEST(MidiOutput, NRPN)
  564. {
  565. typedef VariableSettings<true, true> Settings;
  566. typedef midi::MidiInterface<Transport, Settings> RsMidiInterface;
  567. SerialMock serial;
  568. Transport transport(serial);
  569. RsMidiInterface midi((Transport&)transport);
  570. Buffer buffer;
  571. // 14-bit Value Single Frame
  572. {
  573. buffer.clear();
  574. buffer.resize(13);
  575. midi.begin();
  576. midi.beginNrpn(1242, 12);
  577. midi.sendNrpnValue(12345, 12);
  578. midi.endNrpn(12);
  579. EXPECT_EQ(serial.mTxBuffer.getLength(), 13);
  580. serial.mTxBuffer.read(&buffer[0], 13);
  581. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  582. 0x62, 0x5a,
  583. 0x63, 0x09,
  584. 0x06, 0x60,
  585. 0x26, 0x39,
  586. 0x62, 0x7f,
  587. 0x63, 0x7f}));
  588. }
  589. // MSB/LSB Single Frame
  590. {
  591. buffer.clear();
  592. buffer.resize(13);
  593. midi.begin();
  594. midi.beginNrpn(1242, 12);
  595. midi.sendNrpnValue(12, 42, 12);
  596. midi.endNrpn(12);
  597. EXPECT_EQ(serial.mTxBuffer.getLength(), 13);
  598. serial.mTxBuffer.read(&buffer[0], 13);
  599. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  600. 0x62, 0x5a,
  601. 0x63, 0x09,
  602. 0x06, 0x0c,
  603. 0x26, 0x2a,
  604. 0x62, 0x7f,
  605. 0x63, 0x7f}));
  606. }
  607. // Increment Single Frame
  608. {
  609. buffer.clear();
  610. buffer.resize(11);
  611. midi.begin();
  612. midi.beginNrpn(1242, 12);
  613. midi.sendNrpnIncrement(42, 12);
  614. midi.endNrpn(12);
  615. EXPECT_EQ(serial.mTxBuffer.getLength(), 11);
  616. serial.mTxBuffer.read(&buffer[0], 11);
  617. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  618. 0x62, 0x5a,
  619. 0x63, 0x09,
  620. 0x60, 0x2a,
  621. 0x62, 0x7f,
  622. 0x63, 0x7f}));
  623. }
  624. // Decrement Single Frame
  625. {
  626. buffer.clear();
  627. buffer.resize(11);
  628. midi.begin();
  629. midi.beginNrpn(1242, 12);
  630. midi.sendNrpnDecrement(42, 12);
  631. midi.endNrpn(12);
  632. EXPECT_EQ(serial.mTxBuffer.getLength(), 11);
  633. serial.mTxBuffer.read(&buffer[0], 11);
  634. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  635. 0x62, 0x5a,
  636. 0x63, 0x09,
  637. 0x61, 0x2a,
  638. 0x62, 0x7f,
  639. 0x63, 0x7f}));
  640. }
  641. // Multi Frame
  642. {
  643. buffer.clear();
  644. buffer.resize(21);
  645. midi.begin();
  646. midi.beginNrpn(1242, 12);
  647. midi.sendNrpnValue(12345, 12);
  648. midi.sendNrpnValue(12, 42, 12);
  649. midi.sendNrpnIncrement(42, 12);
  650. midi.sendNrpnDecrement(42, 12);
  651. midi.endNrpn(12);
  652. EXPECT_EQ(serial.mTxBuffer.getLength(), 21);
  653. serial.mTxBuffer.read(&buffer[0], 21);
  654. EXPECT_THAT(buffer, ElementsAreArray({0xbb,
  655. 0x62, 0x5a,
  656. 0x63, 0x09,
  657. 0x06, 0x60,
  658. 0x26, 0x39,
  659. 0x06, 0x0c,
  660. 0x26, 0x2a,
  661. 0x60, 0x2a,
  662. 0x61, 0x2a,
  663. 0x62, 0x7f,
  664. 0x63, 0x7f}));
  665. }
  666. }
  667. TEST(MidiOutput, runningStatusCancellation)
  668. {
  669. typedef VariableSettings<true, false> Settings;
  670. typedef midi::MidiInterface<Transport, Settings> RsMidiInterface;
  671. SerialMock serial;
  672. Transport transport(serial);
  673. RsMidiInterface midi((Transport&)transport);
  674. Buffer buffer;
  675. static const unsigned sysExLength = 13;
  676. static const byte sysEx[sysExLength] = {
  677. 'H','e','l','l','o',',',' ','W','o','r','l','d','!'
  678. };
  679. midi.begin();
  680. midi.sendNoteOn(12, 34, 1);
  681. midi.sendNoteOn(56, 78, 1);
  682. EXPECT_EQ(serial.mTxBuffer.getLength(), 5);
  683. buffer.clear();
  684. buffer.resize(5);
  685. serial.mTxBuffer.read(&buffer[0], 5);
  686. EXPECT_THAT(buffer, ElementsAreArray({
  687. 0x90, 12, 34, 56, 78
  688. }));
  689. midi.sendRealTime(midi::Clock); // Should not reset running status.
  690. midi.sendNoteOn(12, 34, 1);
  691. EXPECT_EQ(serial.mTxBuffer.getLength(), 3);
  692. buffer.clear();
  693. buffer.resize(3);
  694. serial.mTxBuffer.read(&buffer[0], 3);
  695. EXPECT_THAT(buffer, ElementsAreArray({
  696. 0xf8, 12, 34
  697. }));
  698. midi.sendSysEx(sysExLength, sysEx); // Should reset running status.
  699. midi.sendNoteOn(12, 34, 1);
  700. EXPECT_EQ(serial.mTxBuffer.getLength(), 18);
  701. buffer.clear();
  702. buffer.resize(18);
  703. serial.mTxBuffer.read(&buffer[0], 18);
  704. {
  705. static const byte expected[] = {
  706. 0xf0, 'H','e','l','l','o',',',' ','W','o','r','l','d','!', 0xf7,
  707. 0x90, 12, 34
  708. };
  709. EXPECT_THAT(buffer, ElementsAreArray(expected));
  710. }
  711. midi.sendTimeCodeQuarterFrame(42); // Should reset running status.
  712. midi.sendNoteOn(12, 34, 1);
  713. EXPECT_EQ(serial.mTxBuffer.getLength(), 5);
  714. buffer.clear();
  715. buffer.resize(5);
  716. serial.mTxBuffer.read(&buffer[0], 5);
  717. EXPECT_THAT(buffer, ElementsAreArray({
  718. 0xf1, 42,
  719. 0x90, 12, 34
  720. }));
  721. midi.sendSongPosition(42); // Should reset running status.
  722. midi.sendNoteOn(12, 34, 1);
  723. EXPECT_EQ(serial.mTxBuffer.getLength(), 6);
  724. buffer.clear();
  725. buffer.resize(6);
  726. serial.mTxBuffer.read(&buffer[0], 6);
  727. EXPECT_THAT(buffer, ElementsAreArray({
  728. 0xf2, 42, 0,
  729. 0x90, 12, 34
  730. }));
  731. midi.sendSongSelect(42); // Should reset running status.
  732. midi.sendNoteOn(12, 34, 1);
  733. EXPECT_EQ(serial.mTxBuffer.getLength(), 5);
  734. buffer.clear();
  735. buffer.resize(5);
  736. serial.mTxBuffer.read(&buffer[0], 5);
  737. EXPECT_THAT(buffer, ElementsAreArray({
  738. 0xf3, 42,
  739. 0x90, 12, 34
  740. }));
  741. midi.sendTuneRequest(); // Should reset running status.
  742. midi.sendNoteOn(12, 34, 1);
  743. EXPECT_EQ(serial.mTxBuffer.getLength(), 4);
  744. buffer.clear();
  745. buffer.resize(4);
  746. serial.mTxBuffer.read(&buffer[0], 4);
  747. EXPECT_THAT(buffer, ElementsAreArray({
  748. 0xf6,
  749. 0x90, 12, 34
  750. }));
  751. }
  752. END_UNNAMED_NAMESPACE