LCOV - code coverage report
Current view: top level - zephyr/audio - midi.h Coverage Total Hit
Test: new.info Lines: 98.5 % 65 64
Test Date: 2025-10-20 12:20:01

            Line data    Source code
       1            0 : /*
       2              :  * Copyright (c) 2024 Titouan Christophe
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : #ifndef ZEPHYR_INCLUDE_AUDIO_MIDI_H_
       8              : #define ZEPHYR_INCLUDE_AUDIO_MIDI_H_
       9              : 
      10              : #ifdef __cplusplus
      11              : extern "C" {
      12              : #endif
      13              : 
      14              : #include <stdint.h>
      15              : 
      16              : /**
      17              :  * @brief Universal MIDI Packet definitions
      18              :  * @defgroup midi_ump MIDI2 Universal MIDI Packet definitions
      19              :  * @ingroup audio_interface
      20              :  * @since 4.1
      21              :  * @version 0.1.0
      22              :  * @{
      23              :  */
      24              : 
      25              : /**
      26              :  * @defgroup ump112 Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol
      27              :  * @ingroup midi_ump
      28              :  * @{
      29              :  * @details Definitions based on the following document
      30              :  * <a href="https://midi.org/universal-midi-packet-ump-and-midi-2-0-protocol-specification">
      31              :  * Universal MIDI Packet (UMP) Format and MIDI 2.0 Protocol
      32              :  * With MIDI 1.0 Protocol in UMP Format - Document version 1.1.2
      33              :  * (MIDI Association Document: M2-104-UM)
      34              :  * </a>
      35              :  * @}
      36              :  */
      37              : 
      38              : /**
      39              :  * @brief      Universal MIDI Packet container
      40              :  */
      41            1 : struct midi_ump {
      42            1 :         uint32_t data[4]; /**< Raw content, in the CPU native endianness */
      43              : };
      44              : 
      45              : /**
      46              :  * @defgroup midi_ump_mt Message types
      47              :  * @ingroup midi_ump
      48              :  * @see ump112: 2.1.4 Message Type (MT) Allocation
      49              :  * @{
      50              :  */
      51              : 
      52              : /** Utility Messages */
      53            1 : #define UMP_MT_UTILITY             0x00
      54              : /** System Real Time and System Common Messages (except System Exclusive) */
      55            1 : #define UMP_MT_SYS_RT_COMMON       0x01
      56              : /** MIDI 1.0 Channel Voice Messages */
      57            1 : #define UMP_MT_MIDI1_CHANNEL_VOICE 0x02
      58              : /** 64 bits Data Messages (including System Exclusive) */
      59            1 : #define UMP_MT_DATA_64             0x03
      60              : /** MIDI 2.0 Channel Voice Messages */
      61            1 : #define UMP_MT_MIDI2_CHANNEL_VOICE 0x04
      62              : /** 128 bits Data Messages */
      63            1 : #define UMP_MT_DATA_128            0x05
      64              : /** Flex Data Messages */
      65            1 : #define UMP_MT_FLEX_DATA           0x0d
      66              : /**
      67              :  * UMP Stream Message
      68              :  * @see midi_ump_stream
      69              :  */
      70            1 : #define UMP_MT_UMP_STREAM          0x0f
      71              : /** @} */
      72              : 
      73              : /**
      74              :  * @brief      Message Type field of a Universal MIDI Packet
      75              :  * @param[in]  ump    Universal MIDI Packet
      76              :  * @see midi_ump_mt
      77              :  */
      78            1 : #define UMP_MT(ump) \
      79              :         ((ump).data[0] >> 28)
      80              : 
      81              : /**
      82              :  * There are 16 UMP message types, each of which can be 1 to 4 uint32 long.
      83              :  * Hence this packed representation of 16x2b array as an uint32 lookup table
      84              :  */
      85            1 : #define UMP_NUM_WORDS_LOOKUP_TABLE \
      86              :         ((0U << 0) | (0U << 2) | (0U << 4) | (1U << 6) | \
      87              :         (1U << 8) | (3U << 10) | (0U << 12) | (0U << 14) | \
      88              :         (1U << 16) | (1U << 18) | (1U << 20) | (2U << 22) | \
      89              :         (2U << 24) | (3U << 26) | (3U << 28) | (3U << 30))
      90              : 
      91              : /**
      92              :  * @brief      Size of a Universal MIDI Packet, in 32bit words
      93              :  * @param[in]  ump    Universal MIDI Packet
      94              :  * @see ump112: 2.1.4 Message Type (MT) Allocation
      95              :  */
      96            1 : #define UMP_NUM_WORDS(ump) \
      97              :         (1 + ((UMP_NUM_WORDS_LOOKUP_TABLE >> (2 * UMP_MT(ump))) & 3))
      98              : 
      99              : /**
     100              :  * @brief      MIDI group field of a Universal MIDI Packet
     101              :  * @param[in]  ump    Universal MIDI Packet
     102              :  */
     103            1 : #define UMP_GROUP(ump) \
     104              :         (((ump).data[0] >> 24) & 0xF)
     105              : 
     106              : /**
     107              :  * @brief      Status byte of a MIDI channel voice or system message
     108              :  * @param[in]  ump    Universal MIDI Packet (containing a MIDI1 event)
     109              :  * @see midi_ump_sys
     110              :  */
     111            1 : #define UMP_MIDI_STATUS(ump) \
     112              :         (((ump).data[0] >> 16) & 0xFF)
     113              : /**
     114              :  * @brief      Command of a MIDI channel voice message
     115              :  * @param[in]  ump    Universal MIDI Packet (containing a MIDI event)
     116              :  * @see midi_ump_cmd
     117              :  */
     118            1 : #define UMP_MIDI_COMMAND(ump) \
     119              :         (UMP_MIDI_STATUS(ump) >> 4)
     120              : /**
     121              :  * @brief      Channel of a MIDI channel voice message
     122              :  * @param[in]  ump    Universal MIDI Packet (containing a MIDI event)
     123              :  */
     124            1 : #define UMP_MIDI_CHANNEL(ump) \
     125              :         (UMP_MIDI_STATUS(ump) & 0xF)
     126              : /**
     127              :  * @brief      First parameter of a MIDI1 channel voice or system message
     128              :  * @param[in]  ump     Universal MIDI Packet (containing a MIDI1 message)
     129              :  */
     130            1 : #define UMP_MIDI1_P1(ump) \
     131              :         (((ump).data[0] >> 8) & 0x7F)
     132              : /**
     133              :  * @brief      Second parameter of a MIDI1 channel voice or system message
     134              :  * @param[in]  ump     Universal MIDI Packet (containing a MIDI1 message)
     135              :  */
     136            1 : #define UMP_MIDI1_P2(ump) \
     137              :         ((ump).data[0] & 0x7F)
     138              : 
     139              : /**
     140              :  * @brief      Initialize a UMP with a MIDI1 channel voice message
     141              :  * @remark     For messages that take a single parameter, p2 is ignored by the receiver.
     142              :  * @param      group    The UMP group
     143              :  * @param      command  The MIDI1 command
     144              :  * @param      channel  The MIDI1 channel number
     145              :  * @param      p1       The 1st MIDI1 parameter
     146              :  * @param      p2       The 2nd MIDI1 parameter
     147              :  */
     148            1 : #define UMP_MIDI1_CHANNEL_VOICE(group, command, channel, p1, p2) \
     149              :         (struct midi_ump) {.data = {                             \
     150              :                 (UMP_MT_MIDI1_CHANNEL_VOICE << 28)               \
     151              :                 | (((group) & 0x0f) << 24)                       \
     152              :                 | (((command) & 0x0f) << 20)                     \
     153              :                 | (((channel) & 0x0f) << 16)                     \
     154              :                 | (((p1) & 0x7f) << 8)                           \
     155              :                 | ((p2) & 0x7f)                                  \
     156              :         }}
     157              : 
     158              : /**
     159              :  * @defgroup midi_ump_cmd MIDI commands
     160              :  * @ingroup midi_ump
     161              :  * @see ump112: 7.3 MIDI 1.0 Channel Voice Messages
     162              :  * @remark When UMP_MT(x)=UMP_MT_MIDI1_CHANNEL_VOICE or UMP_MT_MIDI2_CHANNEL_VOICE,
     163              :  *         then UMP_MIDI_COMMAND(x) may be one of:
     164              :  * @{
     165              :  */
     166            1 : #define UMP_MIDI_NOTE_OFF        0x8 /**< Note Off (p1=note number, p2=velocity) */
     167            1 : #define UMP_MIDI_NOTE_ON         0x9 /**< Note On (p1=note number, p2=velocity) */
     168            1 : #define UMP_MIDI_AFTERTOUCH      0xa /**< Polyphonic aftertouch (p1=note number, p2=data) */
     169            1 : #define UMP_MIDI_CONTROL_CHANGE  0xb /**< Control Change (p1=index, p2=data) */
     170            1 : #define UMP_MIDI_PROGRAM_CHANGE  0xc /**< Control Change (p1=program) */
     171            1 : #define UMP_MIDI_CHAN_AFTERTOUCH 0xd /**< Channel aftertouch (p1=data) */
     172            1 : #define UMP_MIDI_PITCH_BEND      0xe /**< Pitch bend (p1=lsb, p2=msb) */
     173              : /** @} */
     174              : 
     175              : /**
     176              :  * @brief      Initialize a UMP with a System Real Time and System Common Message
     177              :  * @remark     For messages that take only one (or no) parameter, p2 (and p1)
     178              :  *             are ignored by the receiver.
     179              :  * @param      group    The UMP group
     180              :  * @param      status   The status byte
     181              :  * @param      p1       The 1st parameter
     182              :  * @param      p2       The 2nd parameter
     183              :  */
     184            1 : #define UMP_SYS_RT_COMMON(group, status, p1, p2) \
     185              :         (struct midi_ump) {.data = {             \
     186              :                 (UMP_MT_SYS_RT_COMMON << 28)     \
     187              :                 | (((group) & 0x0f) << 24)       \
     188              :                 | ((status) << 16)               \
     189              :                 | (((p1) & 0x7f) << 8)           \
     190              :                 | ((p2) & 0x7f)                  \
     191              :         }}
     192              : 
     193              : /**
     194              :  * @defgroup midi_ump_sys System common and System Real Time message status
     195              :  * @ingroup midi_ump
     196              :  * @see ump112: 7.6 System Common and System Real Time Messages
     197              :  *
     198              :  * @remark When UMP_MT(x)=UMP_MT_SYS_RT_COMMON,
     199              :  *         then UMP_MIDI_STATUS(x) may be one of:
     200              :  * @{
     201              :  */
     202            1 : #define UMP_SYS_MIDI_TIME_CODE 0xf1 /**< MIDI Time Code (no param) */
     203            1 : #define UMP_SYS_SONG_POSITION  0xf2 /**< Song Position Pointer (p1=lsb, p2=msb) */
     204            1 : #define UMP_SYS_SONG_SELECT    0xf3 /**< Song Select (p1=song number) */
     205            1 : #define UMP_SYS_TUNE_REQUEST   0xf6 /**< Tune Request (no param) */
     206            1 : #define UMP_SYS_TIMING_CLOCK   0xf8 /**< Timing Clock (no param) */
     207            1 : #define UMP_SYS_START          0xfa /**< Start (no param) */
     208            1 : #define UMP_SYS_CONTINUE       0xfb /**< Continue (no param) */
     209            1 : #define UMP_SYS_STOP           0xfc /**< Stop (no param) */
     210            1 : #define UMP_SYS_ACTIVE_SENSING 0xfe /**< Active sensing (no param) */
     211            1 : #define UMP_SYS_RESET          0xff /**< Reset (no param) */
     212              : /** @} */
     213              : 
     214              : 
     215              : /**
     216              :  * @defgroup midi_ump_stream UMP Stream specific fields
     217              :  * @ingroup midi_ump
     218              :  * @see ump112: 7.1 UMP Stream Messages
     219              :  *
     220              :  * @{
     221              :  */
     222              : 
     223              : /**
     224              :  * @brief      Format of a UMP Stream message
     225              :  * @param[in]  ump     Universal MIDI Packet (containing a UMP Stream message)
     226              :  * @see midi_ump_stream_format
     227              :  */
     228            1 : #define UMP_STREAM_FORMAT(ump) \
     229              :         (((ump).data[0] >> 26) & 0x03)
     230              : 
     231              : /**
     232              :  * @defgroup midi_ump_stream_format UMP Stream format
     233              :  * @ingroup midi_ump_stream
     234              :  * @see ump112: 7.1 UMP Stream Messages: Format
     235              :  * @remark When UMP_MT(x)=UMP_MT_UMP_STREAM,
     236              :  *         then UMP_STREAM_FORMAT(x) may be one of:
     237              :  * @{
     238              :  */
     239              : 
     240              : /** Complete message in one UMP */
     241            1 : #define UMP_STREAM_FORMAT_COMPLETE 0x00
     242              : /** Start of a message which spans two or more UMPs */
     243            1 : #define UMP_STREAM_FORMAT_START    0x01
     244              : /** Continuing a message which spans three or more UMPs.
     245              :  *  There might be multiple Continue UMPs in a single message
     246              :  */
     247            1 : #define UMP_STREAM_FORMAT_CONTINUE 0x02
     248              : /** End of message which spans two or more UMPs */
     249            1 : #define UMP_STREAM_FORMAT_END      0x03
     250              : 
     251              : /** @} */
     252              : 
     253              : /**
     254              :  * @brief      Status field of a UMP Stream message
     255              :  * @param[in]  ump     Universal MIDI Packet (containing a UMP Stream message)
     256              :  * @see midi_ump_stream_status
     257              :  */
     258            1 : #define UMP_STREAM_STATUS(ump) \
     259              :         (((ump).data[0] >> 16) & 0x3FF)
     260              : 
     261              : /**
     262              :  * @defgroup midi_ump_stream_status UMP Stream status
     263              :  * @ingroup midi_ump_stream
     264              :  * @see ump112: 7.1 UMP Stream Messages
     265              :  * @remark When UMP_MT(x)=UMP_MT_UMP_STREAM,
     266              :  *         then UMP_STREAM_STATUS(x) may be one of:
     267              :  * @{
     268              :  */
     269              : 
     270              : /** Endpoint Discovery Message */
     271            1 : #define UMP_STREAM_STATUS_EP_DISCOVERY 0x00
     272              : /** Endpoint Info Notification Message */
     273            1 : #define UMP_STREAM_STATUS_EP_INFO      0x01
     274              : /** Device Identity Notification Message */
     275            1 : #define UMP_STREAM_STATUS_DEVICE_IDENT 0x02
     276              : /** Endpoint Name Notification */
     277            1 : #define UMP_STREAM_STATUS_EP_NAME      0x03
     278              : /** Product Instance Id Notification Message */
     279            1 : #define UMP_STREAM_STATUS_PROD_ID      0x04
     280              : /** Stream Configuration Request Message */
     281            1 : #define UMP_STREAM_STATUS_CONF_REQ     0x05
     282              : /** Stream Configuration Notification Message */
     283            1 : #define UMP_STREAM_STATUS_CONF_NOTIF   0x06
     284              : /** Function Block Discovery Message */
     285            1 : #define UMP_STREAM_STATUS_FB_DISCOVERY 0x10
     286              : /** Function Block Info Notification */
     287            1 : #define UMP_STREAM_STATUS_FB_INFO      0x11
     288              : /** Function Block Name Notification */
     289            1 : #define UMP_STREAM_STATUS_FB_NAME      0x12
     290              : /** @} */
     291              : 
     292              : /**
     293              :  * @brief      Filter bitmap of an Endpoint Discovery message
     294              :  * @param[in]  ump     Universal MIDI Packet (containing an Endpoint Discovery message)
     295              :  * @see ump112: 7.1.1 Endpoint Discovery Message
     296              :  * @see midi_ump_ep_disc
     297              :  */
     298            1 : #define UMP_STREAM_EP_DISCOVERY_FILTER(ump) \
     299              :         ((ump).data[1] & 0xFF)
     300              : 
     301              : /**
     302              :  * @defgroup midi_ump_ep_disc UMP Stream endpoint discovery message filter bits
     303              :  * @ingroup midi_ump_stream
     304              :  * @see ump112: 7.1.1 Fig. 12: Endpoint Discovery Message Filter Bitmap Field
     305              :  * @remark When UMP_MT(x)=UMP_MT_UMP_STREAM and
     306              :  *         UMP_STREAM_STATUS(x)=UMP_STREAM_STATUS_EP_DISCOVERY,
     307              :  *         then UMP_STREAM_EP_DISCOVERY_FILTER(x) may be an ORed combination of:
     308              :  * @{
     309              :  */
     310              : 
     311              : /** Requesting an Endpoint Info Notification */
     312            1 : #define UMP_EP_DISC_FILTER_EP_INFO    BIT(0)
     313              : /** Requesting a Device Identity Notification */
     314            1 : #define UMP_EP_DISC_FILTER_DEVICE_ID  BIT(1)
     315              : /** Requesting an Endpoint Name Notification */
     316            1 : #define UMP_EP_DISC_FILTER_EP_NAME    BIT(2)
     317              : /** Requesting a Product Instance Id Notification */
     318            1 : #define UMP_EP_DISC_FILTER_PRODUCT_ID BIT(3)
     319              : /** Requesting a Stream Configuration Notification */
     320            1 : #define UMP_EP_DISC_FILTER_STREAM_CFG BIT(4)
     321              : /** @} */
     322              : 
     323              : /**
     324              :  * @brief      Filter bitmap of a Function Block Discovery message
     325              :  * @param[in]  ump     Universal MIDI Packet (containing a Function Block Discovery message)
     326              :  * @see ump112: 7.1.7 Function Block Discovery Message
     327              :  * @see midi_ump_fb_disc
     328              :  */
     329            1 : #define UMP_STREAM_FB_DISCOVERY_FILTER(ump) \
     330              :         ((ump).data[0] & 0xFF)
     331              : 
     332              : /**
     333              :  * @brief      Block number requested in a Function Block Discovery message
     334              :  * @param[in]  ump     Universal MIDI Packet (containing a Function Block Discovery message)
     335              :  * @see ump112: 7.1.7 Function Block Discovery Message
     336              :  */
     337            1 : #define UMP_STREAM_FB_DISCOVERY_NUM(ump) \
     338              :         (((ump).data[0] >> 8) & 0xFF)
     339              : 
     340              : /**
     341              :  * @defgroup midi_ump_fb_disc UMP Stream Function Block discovery message filter bits
     342              :  * @ingroup midi_ump_stream
     343              :  * @see ump112: 7.1.7 Fig. 21: Function Block Discovery Filter Bitmap Field Format
     344              :  * @remark When UMP_MT(x)=UMP_MT_UMP_STREAM and
     345              :  *         UMP_STREAM_STATUS(x)=UMP_STREAM_STATUS_FB_DISCOVERY,
     346              :  *         then UMP_STREAM_FB_DISCOVERY_FILTER(x) may be an ORed combination of:
     347              :  * @{
     348              :  */
     349              : /** Requesting a Function Block Info Notification */
     350            1 : #define UMP_FB_DISC_FILTER_INFO BIT(0)
     351              : /** Requesting a Function Block Name Notification */
     352            1 : #define UMP_FB_DISC_FILTER_NAME BIT(1)
     353              : /** @} */
     354              : 
     355              : /** @} */
     356              : 
     357              : /** @} */
     358              : 
     359              : #ifdef __cplusplus
     360              : }
     361              : #endif
     362              : 
     363              : #endif
        

Generated by: LCOV version 2.0-1