LCOV - code coverage report
Current view: top level - src/MIDI_Interfaces - USBMIDI_Interface.hpp (source / functions) Hit Total Coverage
Test: 91b605873905a6fcb78324052c97dbac10849539 Lines: 7 9 77.8 %
Date: 2022-11-08 01:34:37 Functions: 3 5 60.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "MIDI_Interface.hpp"
       4             : #include "USBMIDI/USBMIDI.hpp"
       5             : #include "USBMIDI_Sender.hpp"
       6             : #include <AH/Error/Error.hpp>
       7             : #include <AH/Teensy/TeensyUSBTypes.hpp>
       8             : #include <MIDI_Parsers/USBMIDI_Parser.hpp>
       9             : 
      10             : AH_DIAGNOSTIC_WERROR()
      11             : 
      12             : BEGIN_CS_NAMESPACE
      13             : 
      14             : /**
      15             :  * @brief   A class for MIDI interfaces sending MIDI messages over a USB MIDI
      16             :  *          connection.
      17             :  */
      18             : template <class Backend>
      19             : class GenericUSBMIDI_Interface : public MIDI_Interface {
      20             :   public:
      21             :     /**
      22             :      * @brief   Construct a new GenericUSBMIDI_Interface.
      23             :      */
      24             :     template <class... Args>
      25          29 :     GenericUSBMIDI_Interface(Args &&...args)
      26             :         : backend(std::forward<Args>(args)...),
      27          29 :           alwaysSendImmediately_(backend.preferImmediateSend()) {}
      28             : 
      29             :   private:
      30             :     // MIDI send implementations
      31             :     void sendChannelMessageImpl(ChannelMessage) override;
      32             :     void sendSysCommonImpl(SysCommonMessage) override;
      33             :     void sendSysExImpl(SysExMessage) override;
      34             :     void sendRealTimeImpl(RealTimeMessage) override;
      35           0 :     void sendNowImpl() override { backend.sendNow(); }
      36             : 
      37             :   private:
      38             : #if !DISABLE_PIPES
      39           0 :     void handleStall() override { MIDI_Interface::handleStall(this); }
      40             : #endif
      41             : 
      42             :   public:
      43             :     void begin() override;
      44             :     void update() override;
      45             : 
      46             :   public:
      47             :     /// @name   Reading incoming MIDI messages
      48             :     /// @{
      49             : 
      50             :     /// Try reading and parsing a single incoming MIDI message.
      51             :     /// @return Returns the type of the read message, or
      52             :     ///         `MIDIReadEvent::NO_MESSAGE` if no MIDI message was available.
      53             :     MIDIReadEvent read();
      54             : 
      55             :     /// Return the received channel voice message.
      56             :     ChannelMessage getChannelMessage() const;
      57             :     /// Return the received system common message.
      58             :     SysCommonMessage getSysCommonMessage() const;
      59             :     /// Return the received real-time message.
      60             :     RealTimeMessage getRealTimeMessage() const;
      61             :     /// Return the received system exclusive message.
      62             :     SysExMessage getSysExMessage() const;
      63             : 
      64             :     /// @}
      65             : 
      66             :   public:
      67             :     /// @name Underlying USB communication
      68             :     /// @{
      69             : 
      70             :     /// The (platform-specific) backend used for MIDI over USB communication.
      71             :     Backend backend;
      72             : 
      73             :   private:
      74             :     /// Functor to send USB MIDI packets.
      75             :     struct Sender {
      76             :         GenericUSBMIDI_Interface *iface;
      77          28 :         void operator()(Cable cn, MIDICodeIndexNumber cin, uint8_t d0,
      78             :                         uint8_t d1, uint8_t d2) {
      79          28 :             uint8_t cn_cin = (cn.getRaw() << 4) | uint8_t(cin);
      80          28 :             iface->backend.write({cn_cin, d0, d1, d2});
      81          28 :         }
      82             :     };
      83             :     /// @}
      84             : 
      85             :   private:
      86             :     /// Parses USB packets into MIDI messages.
      87             :     USBMIDI_Parser parser;
      88             :     /// Sends USB MIDI messages.
      89             :     USBMIDI_Sender sender;
      90             :     /// @see neverSendImmediately()
      91             :     bool alwaysSendImmediately_ = true;
      92             : 
      93             :   public:
      94             :     /// @name   Buffering USB packets
      95             :     /// @{
      96             : 
      97             :     /// Check if this USB interface always sends its USB packets immediately
      98             :     /// after sending a MIDI message. The default value depends on the MIDI USB
      99             :     /// backend being used: `true` for the `MIDIUSB` library, and `false` for
     100             :     /// the Teensy Core USB MIDI functions (because they have a short timeout).
     101             :     bool alwaysSendsImmediately() const { return alwaysSendImmediately_; }
     102             :     /// Don't send the USB packets immediately after sending a MIDI message.
     103             :     /// By disabling immediate transmission, packets are buffered until you
     104             :     /// call @ref sendNow() or until a timeout is reached, so multiple MIDI
     105             :     /// messages can be transmitted in a single USB packet. This is more
     106             :     /// efficient and results in a higher maximum bandwidth, but it could
     107             :     /// increase latency when used incorrectly.
     108             :     void neverSendImmediately() { alwaysSendImmediately_ = false; }
     109             :     /// Send the USB packets immediately after sending a MIDI message.
     110             :     /// @see @ref neverSendImmediately()
     111             :     void alwaysSendImmediately() { alwaysSendImmediately_ = true; }
     112             : 
     113             :     /// @}
     114             : };
     115             : 
     116             : END_CS_NAMESPACE
     117             : 
     118             : #include "USBMIDI_Interface.ipp"
     119             : 
     120             : #if defined(TEENSYDUINO) && !defined(TEENSY_MIDIUSB_ENABLED)
     121             : #warning                                                                       \
     122             :     "Teensy: USB MIDI not enabled. Enable it from the Tools > USB Type menu."
     123             : #define CS_USB_MIDI_DISABLED
     124             : #endif
     125             : 
     126             : // If MIDI over USB is supported
     127             : #if (!defined(CS_USB_MIDI_NOT_SUPPORTED) && !defined(CS_USB_MIDI_DISABLED)) || \
     128             :     !defined(ARDUINO)
     129             : 
     130             : BEGIN_CS_NAMESPACE
     131             : 
     132             : /**
     133             :  * @brief   A class for MIDI interfaces sending MIDI messages over a USB MIDI
     134             :  *          connection.
     135             :  * 
     136             :  * On boards that support it, this will create a native MIDI over USB interface
     137             :  * using the platform-specific libraries (e.g. MIDIUSB for Arduino Leonardo, or 
     138             :  * the Core usbMIDI library for Teensy).  
     139             :  * On boards without native USB support, it'll fall back to a serial MIDI 
     140             :  * interface at the default @ref MIDI_BAUD "MIDI baud rate" on the UART 
     141             :  * connected to the Serial to USB chip. This can be used with custom 
     142             :  * MIDI over USB firmware for the Serial to USB chip.
     143             :  * 
     144             :  * @note    See @ref md_pages_MIDI-over-USB for more information.
     145             :  * 
     146             :  * @ingroup MIDIInterfaces
     147             :  */
     148             : class USBMIDI_Interface
     149             :     : public GenericUSBMIDI_Interface<USBDeviceMIDIBackend> {
     150             :   public:
     151          29 :     USBMIDI_Interface() = default;
     152             :     using MIDIUSBPacket_t = USBDeviceMIDIBackend::MIDIUSBPacket_t;
     153             : };
     154             : 
     155             : END_CS_NAMESPACE
     156             : 
     157             : // If the main MCU doesn't have a USB connection:
     158             : // Fall back on Serial connection at the hardware MIDI baud rate.
     159             : // (Can be used with HIDUINO or USBMidiKliK.)
     160             : #elif !defined(CS_USB_MIDI_DISABLED)
     161             : 
     162             : #include "SerialMIDI_Interface.hpp"
     163             : 
     164             : BEGIN_CS_NAMESPACE
     165             : 
     166             : /**
     167             :  * @brief   A class for MIDI interfaces sending MIDI messages over a USB MIDI
     168             :  *          connection.
     169             :  * 
     170             :  * @note    See @ref md_pages_MIDI-over-USB for more information.
     171             :  * 
     172             :  * @ingroup MIDIInterfaces
     173             :  */
     174             : class USBMIDI_Interface : public USBSerialMIDI_Interface {
     175             :   public:
     176             :     /**
     177             :      * @brief   Construct a new USBMIDI_Interface.
     178             :      */
     179             :     USBMIDI_Interface() : USBSerialMIDI_Interface(MIDI_BAUD) {}
     180             : };
     181             : 
     182             : END_CS_NAMESPACE
     183             : 
     184             : #endif
     185             : 
     186             : AH_DIAGNOSTIC_POP()

Generated by: LCOV version 1.15