LCOV - code coverage report
Current view: top level - src/MIDI_Interfaces/BLEMIDI - BufferedBLEMIDIParser.hpp (source / functions) Coverage Total Hit
Test: 73449d9b107c772cf65493691543348214e5d5eb Lines: 94.3 % 35 33
Test Date: 2026-06-06 17:44:35 Functions: 100.0 % 3 3
Legend: Lines:     hit not hit

            Line data    Source code
       1              : #pragma once
       2              : 
       3              : #include <Settings/NamespaceSettings.hpp>
       4              : 
       5              : #include "BLERingBuf.hpp"
       6              : #include <MIDI_Parsers/AnyMIDI_Message.hpp>
       7              : #include <MIDI_Parsers/BLEMIDIParser.hpp>
       8              : #include <MIDI_Parsers/SerialMIDI_Parser.hpp>
       9              : 
      10              : BEGIN_CS_NAMESPACE
      11              : 
      12              : /// FIFO buffer that you can push BLE packets into, and pop MIDI messages out of.
      13              : /// If @p SizeT is chosen to be atomic, one thread can push packets, and another
      14              : /// thread can pop MIDI messages, without additional synchronization.
      15              : template <uint16_t Capacity, class SizeT = NonatomicBLERingBufSize<uint16_t>>
      16              : class BufferedBLEMIDIParser {
      17              :   private:
      18              :     /// Contains incoming data to be parsed.
      19              :     BLERingBuf<Capacity, SizeT> ble_buffer {};
      20              :     /// Parses the (chunked) BLE packet obtained from @ref ble_buffer.
      21              :     BLEMIDIParser ble_parser {nullptr, 0};
      22              :     /// Parser for MIDI data extracted from the BLE packet by @ref ble_parser.
      23              :     SerialMIDI_Parser parser {false};
      24              : 
      25              :   public:
      26              :     using IncomingMIDIMessage = AnyMIDIMessage;
      27              : 
      28              :     /// Add a new BLE packet or chunk to the buffer.
      29           15 :     bool pushPacket(BLEDataView packet,
      30              :                     BLEDataType type = BLEDataType::Packet) {
      31           15 :         return ble_buffer.push(packet, type);
      32              :     }
      33              : 
      34              :     /// Retrieve and remove a single incoming MIDI message from the buffer.
      35           52 :     bool popMessage(IncomingMIDIMessage &incomingMessage) {
      36              :         // Try reading a MIDI message from the parser
      37           52 :         auto try_read = [&] {
      38           67 :             MIDIReadEvent event = parser.pull(ble_parser);
      39           67 :             switch (event) {
      40           33 :                 case MIDIReadEvent::CHANNEL_MESSAGE:
      41           66 :                     incomingMessage = {parser.getChannelMessage(),
      42           33 :                                        ble_parser.getTimestamp()};
      43           33 :                     return true;
      44            4 :                 case MIDIReadEvent::SYSEX_CHUNK: // fallthrough
      45              :                 case MIDIReadEvent::SYSEX_MESSAGE:
      46            8 :                     incomingMessage = {parser.getSysExMessage(),
      47            4 :                                        ble_parser.getTimestamp()};
      48            4 :                     return true;
      49            2 :                 case MIDIReadEvent::REALTIME_MESSAGE:
      50            4 :                     incomingMessage = {parser.getRealTimeMessage(),
      51            2 :                                        ble_parser.getTimestamp()};
      52            2 :                     return true;
      53            1 :                 case MIDIReadEvent::SYSCOMMON_MESSAGE:
      54            2 :                     incomingMessage = {parser.getSysCommonMessage(),
      55            1 :                                        ble_parser.getTimestamp()};
      56            1 :                     return true;
      57           27 :                 case MIDIReadEvent::NO_MESSAGE: return false;
      58              :                 default: break; // LCOV_EXCL_LINE
      59              :             }
      60            0 :             return false;
      61              :         };
      62           15 :         while (true) {
      63              :             // Try reading a MIDI message from the current buffer
      64           67 :             if (try_read())
      65           40 :                 return true; // success, incomingMessage updated
      66              :             // Get the next chunk of the BLE packet (if available)
      67           27 :             BLEDataView chunk;
      68           27 :             auto popped = ble_buffer.pop(chunk);
      69           27 :             if (popped == BLEDataType::None)
      70           12 :                 return false; // no more BLE data available
      71           15 :             else if (popped == BLEDataType::Continuation)
      72            0 :                 ble_parser.extend(chunk.data, chunk.length); // same BLE packet
      73           15 :             else if (popped == BLEDataType::Packet)
      74           15 :                 ble_parser = {chunk.data, chunk.length}; // new BLE packet
      75              :         }
      76              :     }
      77              : };
      78              : 
      79              : END_CS_NAMESPACE
        

Generated by: LCOV version 2.4-beta