LCOV - code coverage report
Current view: top level - src/engraving/compat/midi - midicoreevent.h Coverage Total Hit
Test: filtered_coverage.info Lines: 100.0 % 29 29
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2022 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #ifndef MU_ENGRAVING_COMPAT_MIDICOREEVENT_H
      24              : #define MU_ENGRAVING_COMPAT_MIDICOREEVENT_H
      25              : 
      26              : #include <cstdint>
      27              : 
      28              : #include "global/allocator.h"
      29              : 
      30              : namespace mu::engraving {
      31              : struct PitchWheelSpecs {
      32              :     //! @note amplitude of the pitch wheel in semitones
      33              :     uint16_t mAmplitude{ 12 };
      34              : 
      35              :     //! @note absolute limit of the  wheel pitch value (thus,  pitch shift can be set using values from {-mLimit, mLimit} interval
      36              :     uint16_t mLimit    { 8192 };
      37              : 
      38              :     //! @note step of pith wheel in ticks
      39              :     uint16_t mStep     { 10 };
      40              : };
      41              : 
      42              : //---------------------------------------------------------
      43              : //   Event types
      44              : //---------------------------------------------------------
      45              : 
      46              : enum EventType {
      47              :     ME_INVALID    = 0,
      48              :     ME_NOTEOFF    = 0x80,
      49              :     ME_NOTEON     = 0x90,
      50              :     ME_POLYAFTER  = 0xa0,
      51              :     ME_CONTROLLER = 0xb0,   //! Control change message
      52              :     ME_PROGRAM    = 0xc0,   //! Program change message
      53              :     ME_AFTERTOUCH = 0xd0,   //! Channel pressure message
      54              :     ME_PITCHBEND  = 0xe0,
      55              :     ME_SYSEX      = 0xf0,
      56              :     ME_META       = 0xff,
      57              :     ME_SONGPOS    = 0xf2,
      58              :     ME_ENDSYSEX   = 0xf7,
      59              :     ME_CLOCK      = 0xf8,
      60              :     ME_START      = 0xfa,
      61              :     ME_CONTINUE   = 0xfb,
      62              :     ME_STOP       = 0xfc,
      63              :     ME_SENSE      = 0xfe,     // active sense (used by yamaha)
      64              : 
      65              :     ME_NOTE       = 0x1,
      66              :     ME_CHORD      = 0x2,
      67              :     ME_TICK1      = 0x3,    // metronome tick akzent
      68              :     ME_TICK2      = 0x4,    // metronome tick
      69              :     ME_EOT        = 0x5
      70              : };
      71              : 
      72              : //---------------------------------------------------------
      73              : //   Midi Meta Events
      74              : //---------------------------------------------------------
      75              : 
      76              : enum {
      77              :     META_SEQUENCE_NUMBER = 0,
      78              :     META_TEXT            = 1,
      79              :     META_COPYRIGHT       = 2,
      80              :     META_TRACK_NAME      = 3,
      81              :     META_INSTRUMENT_NAME = 4,
      82              :     META_LYRIC           = 5,
      83              :     META_MARKER          = 6,
      84              :     META_CUE_POINT       = 7,
      85              :     META_PROGRAM_NAME    = 8,   // MIDI Meta Events 8 and 9 were defined as above by the MMA in 1998
      86              :     META_DEVICE_NAME     = 9,   // It is therefore necessary to redefine MuseScore's private meta events
      87              :     META_TRACK_COMMENT   = 0xf,   // Using the block starting 0x10 seems sensible as that is currently clear
      88              :     META_TITLE           = 0x10,       // mscore extension
      89              :     META_SUBTITLE        = 0x11,       // mscore extension
      90              :     META_COMPOSER        = 0x12,     // mscore extension
      91              :     META_TRANSLATOR      = 0x13,     // mscore extension
      92              :     META_POET            = 0x14,     // mscore extension
      93              :     META_PORT_CHANGE     = 0x21,
      94              :     META_CHANNEL_PREFIX  = 0x22,
      95              :     META_EOT             = 0x2f,    // end of track
      96              :     META_TEMPO           = 0x51,
      97              :     META_TIME_SIGNATURE  = 0x58,
      98              :     META_KEY_SIGNATURE   = 0x59,
      99              :     META_SPECIFIC        = 0x7F     // sequencer specific
     100              : };
     101              : 
     102              : //---------------------------------------------------------
     103              : //   Midi Controller
     104              : //---------------------------------------------------------
     105              : 
     106              : enum CntrType {
     107              :     CTRL_HBANK               = 0x00,
     108              :     CTRL_LBANK               = 0x20,
     109              : 
     110              :     CTRL_HDATA               = 0x06,
     111              :     CTRL_LDATA               = 0x26,
     112              : 
     113              :     CTRL_HNRPN               = 0x63,
     114              :     CTRL_LNRPN               = 0x62,
     115              : 
     116              :     CTRL_HRPN                = 0x65,
     117              :     CTRL_LRPN                = 0x64,
     118              : 
     119              :     CTRL_MODULATION          = 0x01,
     120              :     CTRL_BREATH              = 0x02,
     121              :     CTRL_FOOT                = 0x04,
     122              :     CTRL_PORTAMENTO_TIME_MSB = 0x05,
     123              :     CTRL_VOLUME              = 0x07,
     124              :     CTRL_PANPOT              = 0x0a,
     125              :     CTRL_EXPRESSION          = 0x0b,
     126              :     CTRL_PORTAMENTO_TIME_LSB = 0x25,
     127              :     CTRL_SUSTAIN             = 0x40,
     128              :     CTRL_PORTAMENTO          = 0x41,
     129              :     CTRL_SOSTENUTO           = 0x42,
     130              :     CTRL_SOFT_PEDAL          = 0x43,
     131              :     CTRL_HARMONIC_CONTENT    = 0x47,
     132              :     CTRL_RELEASE_TIME        = 0x48,
     133              :     CTRL_ATTACK_TIME         = 0x49,
     134              : 
     135              :     CTRL_BRIGHTNESS          = 0x4a,
     136              :     CTRL_PORTAMENTO_CONTROL  = 0x54,
     137              :     CTRL_REVERB_SEND         = 0x5b,
     138              :     CTRL_CHORUS_SEND         = 0x5d,
     139              :     CTRL_VARIATION_SEND      = 0x5e,
     140              : 
     141              :     CTRL_ALL_SOUNDS_OFF      = 0x78,   // 120
     142              :     CTRL_RESET_ALL_CTRL      = 0x79,   // 121
     143              :     CTRL_LOCAL_OFF           = 0x7a,   // 122
     144              :     CTRL_ALL_NOTES_OFF       = 0x7b,   // 123
     145              : 
     146              :     // special midi events are mapped to internal
     147              :     // controller
     148              :     //
     149              :     CTRL_PROGRAM   = 0x81,
     150              :     /*             = 0x82,*/
     151              :     CTRL_PRESS     = 0x83,
     152              :     CTRL_POLYAFTER = 0x84
     153              : };
     154              : 
     155              : //---------------------------------------------------------
     156              : //   MidiCoreEvent
     157              : //---------------------------------------------------------
     158              : 
     159              : class MidiCoreEvent
     160              : {
     161              :     OBJECT_ALLOCATOR(engraving, MidiCoreEvent)
     162              : protected:
     163              :     uint8_t _type    = 0;
     164              :     uint8_t _channel = 0;
     165              :     uint8_t _a       = 0;
     166              :     uint8_t _b       = 0;
     167              : 
     168              : public:
     169       148487 :     MidiCoreEvent() {}
     170         4573 :     MidiCoreEvent(uint8_t t, uint8_t c, uint8_t a, uint8_t b)
     171         4573 :         : _type(t), _channel(c), _a(a), _b(b) {}
     172              : 
     173              :     void set(uint8_t t, uint8_t c, uint8_t a, uint8_t b)
     174              :     {
     175              :         _type    = t;
     176              :         _channel = c;
     177              :         _a       = a;
     178              :         _b       = b;
     179              :     }
     180              : 
     181        77808 :     uint8_t type() const { return _type; }
     182         9438 :     void  setType(uint8_t t) { _type = t; }
     183        15487 :     uint8_t channel() const { return _channel; }
     184         3093 :     void  setChannel(uint8_t c) { _channel = c; }
     185              : 
     186        57209 :     uint8_t dataA() const { return _a; }
     187         7461 :     uint8_t pitch() const { return _a; }
     188         7923 :     uint8_t controller() const { return _a; }
     189              : 
     190         3450 :     void setDataA(int v) { _a = static_cast<uint8_t>(v); }
     191            3 :     void setPitch(int v) { _a = static_cast<uint8_t>(v); }
     192         1383 :     void setController(int v) { _a = static_cast<uint8_t>(v); }
     193              : 
     194        14273 :     uint8_t dataB() const { return _b; }
     195         7048 :     uint8_t velo() const { return _b; }
     196         5304 :     uint8_t value() const { return _b; }
     197              : 
     198         3450 :     void setDataB(int v) { _b = static_cast<uint8_t>(v); }
     199          506 :     void setVelo(int v) { _b = static_cast<uint8_t>(v); }
     200         1510 :     void setValue(int v) { _b = static_cast<uint8_t>(v); }
     201              : 
     202              :     void setData(int a, int b) { _a = static_cast<uint8_t>(a); _b = static_cast<uint8_t>(b); }
     203        10722 :     void setData(int t, int a, int b) { _type = static_cast<uint8_t>(t); _a = static_cast<uint8_t>(a); _b = static_cast<uint8_t>(b); }
     204              : 
     205         3784 :     bool isChannelEvent() const
     206              :     {
     207         3784 :         switch (_type) {
     208         3325 :         case ME_NOTEOFF:
     209              :         case ME_NOTEON:
     210              :         case ME_POLYAFTER:
     211              :         case ME_CONTROLLER:
     212              :         case ME_PROGRAM:
     213              :         case ME_AFTERTOUCH:
     214              :         case ME_PITCHBEND:
     215              :         case ME_NOTE:
     216              :         case ME_CHORD:
     217         3325 :             return true;
     218          459 :         default:
     219          459 :             break;
     220              :         }
     221              : 
     222          459 :         return false;
     223              :     }
     224              : 
     225            1 :     bool operator==(const MidiCoreEvent& e) const
     226              :     {
     227            1 :         return e._type == _type && e._channel == _channel && e._a == _a && e._b == _b;
     228              :     }
     229              : 
     230              :     uint32_t toPackage() const
     231              :     {
     232              :         union {
     233              :             unsigned char data_as_bytes[4];
     234              :             uint32_t data_as_uint32 = 0;
     235              :         } u;
     236              : 
     237              :         switch (type()) {
     238              :         case EventType::ME_NOTEOFF:
     239              :             u.data_as_bytes[0] = 0x80 | channel();
     240              :             u.data_as_bytes[1] = static_cast<unsigned char>(pitch());
     241              :             u.data_as_bytes[2] = 0;
     242              :             u.data_as_bytes[3] = 0;
     243              :             break;
     244              : 
     245              :         case EventType::ME_NOTEON:
     246              :             u.data_as_bytes[0] = 0x90 | channel();
     247              :             u.data_as_bytes[1] = static_cast<unsigned char>(pitch());
     248              :             u.data_as_bytes[2] = static_cast<unsigned char>(velo());
     249              :             u.data_as_bytes[3] = 0;
     250              :             break;
     251              : 
     252              :         case EventType::ME_CONTROLLER:
     253              :             u.data_as_bytes[0] = 0xB0 | channel();
     254              :             u.data_as_bytes[1] = static_cast<unsigned char>(controller());
     255              :             u.data_as_bytes[2] = static_cast<unsigned char>(value());
     256              :             u.data_as_bytes[3] = 0;
     257              :             break;
     258              : 
     259              :         case EventType::ME_PROGRAM:
     260              :             u.data_as_bytes[0] = 0xC0 | channel();
     261              :             u.data_as_bytes[1] = static_cast<unsigned char>(value());
     262              :             u.data_as_bytes[2] = 0;
     263              :             u.data_as_bytes[3] = 0;
     264              :             break;
     265              : 
     266              :         case EventType::ME_PITCHBEND:
     267              :             u.data_as_bytes[0] = 0xE0 | channel();
     268              :             u.data_as_bytes[1] = pitch() & 0x7F;
     269              :             u.data_as_bytes[2] = static_cast<unsigned char>(pitch() >> 7);
     270              :             u.data_as_bytes[3] = 0;
     271              :             break;
     272              : 
     273              :         default:
     274              :             break;
     275              :         }
     276              :         return u.data_as_uint32;
     277              :     }
     278              : };
     279              : }
     280              : #endif
        

Generated by: LCOV version 2.0-1