Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ There is a growing number of code examples and more detailed documentation avail
* System Message [documentation](docs/system_message.md) and [examples](docs/system_message.examples.cpp)
* Data Message [documentation](docs/data_message.md) and [examples](docs/data_message.examples.cpp)
* Extended Data Message [documentation](docs/extended_data_message.md) and [examples](docs/extended_data_message.examples.cpp)
* Flex Data Message [WIP documentation](docs/flex_data_message.md)
* Stream Message [WIP documentation](docs/stream_message.md)
* Flex Data Message [documentation](docs/flex_data_message.md) and [examples](docs/flex_data_message.examples.cpp)
* Stream Message [documentation](docs/stream_message.md) and [examples](docs/stream_message.examples.cpp)
* Utility Message [documentation](docs/utility_message.md)
* MIDI 1 Byte Stream Helper [WIP documentation](docs/midi1_byte_stream.md) and [examples](docs/midi1_byte_stream.examples.cpp)

Expand Down
72 changes: 44 additions & 28 deletions docs/channel_voice_message.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,71 +13,87 @@ Code examples can be found in [`channel_voice_message.examples.cpp`](channel_voi

Available filter functions are:

bool is_channel_voice_message_with_status(const universal_packet&, status_t);

bool is_note_on_message(const universal_packet&);
bool is_note_off_message(const universal_packet&);
bool is_poly_pressure_message(const universal_packet&);
bool is_control_change_message(const universal_packet&);
bool is_program_change_message(const universal_packet&);
bool is_channel_pressure_message(const universal_packet&);
bool is_channel_pitch_bend_message(const universal_packet&);
```cpp
bool is_channel_voice_message_with_status(const universal_packet&, status_t);

bool is_note_on_message(const universal_packet&);
bool is_note_off_message(const universal_packet&);
bool is_poly_pressure_message(const universal_packet&);
bool is_control_change_message(const universal_packet&);
bool is_program_change_message(const universal_packet&);
bool is_channel_pressure_message(const universal_packet&);
bool is_channel_pitch_bend_message(const universal_packet&);
```

Additionally, one may use

bool is_note_on_with_attribute(const universal_packet&, uint8_t);
bool is_note_off_with_attribute(const universal_packet&, uint8_t);
bool is_note_on_with_pitch_7_9(const universal_packet&);
```cpp
bool is_note_on_with_attribute(const universal_packet&, uint8_t);
bool is_note_off_with_attribute(const universal_packet&, uint8_t);
bool is_note_on_with_pitch_7_9(const universal_packet&);
```

to check for MIDI 2 note messages with attributes.

## Note Message Properties

The following functions are available to extract properties from Note messages:

note_nr_t get_note_nr(const universal_packet&);
pitch_7_9 get_note_pitch(const universal_packet&);
velocity get_note_velocity(const universal_packet&);
```cpp
note_nr_t get_note_nr(const universal_packet&);
pitch_7_9 get_note_pitch(const universal_packet&);
velocity get_note_velocity(const universal_packet&);
```

`get_note_nr` is applicable to _Poly Pressure_ and _Per-Note Controller_ messages, too.

Additionally, one may use

uint8_t get_midi2_note_attribute(const universal_packet&);
uint16_t get_midi2_note_attribute_data(const universal_packet&);
```cpp
uint8_t get_midi2_note_attribute(const universal_packet&);
uint16_t get_midi2_note_attribute_data(const universal_packet&);
```

to retrieve Per Note Attribute type and data.

## Controller Message Properties

Use

controller_t get_controller_nr(const universal_packet&);
controller_value get_controller_value(const universal_packet&);
```cpp
controller_t get_controller_nr(const universal_packet&);
controller_value get_controller_value(const universal_packet&);
```

to extract _Control Change_ message properties.

`get_controller_value` is applicable to _Poly Pressure_, _Registered/Assignable Controller_ and _Per-Note Controller_ messages, too.

Use these functions to retrieve properties of specific messages:

controller_value get_poly_pressure_value(const universal_packet&);
uint7_t get_program_value(const universal_packet&);
controller_value get_channel_pressure_value(const universal_packet&);
pitch_bend get_channel_pitch_bend_value(const universal_packet&);
```cpp
controller_value get_poly_pressure_value(const universal_packet&);
uint7_t get_program_value(const universal_packet&);
controller_value get_channel_pressure_value(const universal_packet&);
pitch_bend get_channel_pitch_bend_value(const universal_packet&);
```

## Conversion between Protocols

One may use

std::optional<midi1_channel_voice_message>
as_midi1_channel_voice_message(const midi2_channel_voice_message_view&);
```cpp
std::optional<midi1_channel_voice_message>
as_midi1_channel_voice_message(const midi2_channel_voice_message_view&);
```

to convert a MIDI 2 Channel Voice Message to its MIDI 1 counterpart and

std::optional<midi2_channel_voice_message>
as_midi2_channel_voice_message(const midi1_channel_voice_message_view&);
```cpp
std::optional<midi2_channel_voice_message>
as_midi2_channel_voice_message(const midi1_channel_voice_message_view&);
```

to convert a MIDI 1 Channel Voice Message to its MIDI 2 counterpart.

**Note:** MIDI 1 <-> MIDI 2 translation rules do require some sequences of MIDI 1 messages to be translated to single MIDI 2 messages and vice versa. The above mentioned functions do not follow these rules. Actually they filter some _Control Change_ messages (mostly related to (N)RPNs) and cannot handle MIDI 2 _Program Change_ messages with `bank` data.
**Note:** MIDI 1 <-> MIDI 2 translation rules do require some sequences of MIDI 1 messages to be translated to single MIDI 2 messages and vice versa. The above mentioned functions do not follow these rules. Actually they filter some _Control Change_ messages (mostly related to (N)RPNs) and cannot handle MIDI 2 _Program Change_ messages with `bank` data.
72 changes: 42 additions & 30 deletions docs/data_message.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,75 @@ Code examples can be found in [`data_message.examples.cpp`](data_message.example

Data Messages are represented by a

struct data_message : universal_packet
{
explicit data_message(status_t);
};
```cpp
struct data_message : universal_packet
{
explicit data_message(status_t);
};
```

Usually one will not use this class directly, but instead

struct sysex7_packet : data_message
{
sysex7_packet(status_t, group_t);
```cpp
struct sysex7_packet : data_message
{
sysex7_packet(status_t, group_t);

packet_format format() const;
packet_format format() const;

uint8_t payload_byte(size_t b) const;
void set_payload_byte(size_t, uint8_t);
uint8_t payload_byte(size_t b) const;
void set_payload_byte(size_t, uint8_t);

size_t payload_size() const;
void set_payload_size(size_t);
size_t payload_size() const;
void set_payload_size(size_t);

void add_payload_byte(uint8_t);
};
void add_payload_byte(uint8_t);
};
```

A `sysex7_packet` can hold a payload of up to six bytes and provides APIs to add or read the payload bytes. Be aware that the payload shall only be 7 bit data.

Instead of using sysex7_packet constructors one can create messages using factory functions:

sysex7_packet make_sysex7_complete_packet(group_t);
sysex7_packet make_sysex7_start_packet(group_t);
sysex7_packet make_sysex7_continue_packet(group_t);
sysex7_packet make_sysex7_end_packet(group_t);
```cpp
sysex7_packet make_sysex7_complete_packet(group_t);
sysex7_packet make_sysex7_start_packet(group_t);
sysex7_packet make_sysex7_continue_packet(group_t);
sysex7_packet make_sysex7_end_packet(group_t);
```

Filtering of Data Messages can be done checking `universal_packet::type()` against
`packet_type::data` or use

bool is_data_message(const universal_packet&);
bool is_sysex7_packet(const universal_packet&);
```cpp
bool is_data_message(const universal_packet&);
bool is_sysex7_packet(const universal_packet&);
```

### SysEx7 Packet View

Once validated being a `sysex7` packet one can create a `sysex7_packet_view`
for a `universal_packet`:

struct sysex7_packet_view
{
explicit sysex7_packet_view(const universal_packet&);
```cpp
struct sysex7_packet_view
{
explicit sysex7_packet_view(const universal_packet&);

group_t group() const;
status_t status() const;
packet_format format() const;
size_t payload_size() const;
uint8_t payload_byte(size_t b) const;
};
group_t group() const;
status_t status() const;
packet_format format() const;
size_t payload_size() const;
uint8_t payload_byte(size_t b) const;
};
```

View members provide accessors to the properties of the message.

The additional

std::optional<sysex7_packet_view> as_sysex7_packet_view(const universal_packet&);
```cpp
std::optional<sysex7_packet_view> as_sysex7_packet_view(const universal_packet&);
```

helper allows to combine packet type check and view creation in a single statement.
76 changes: 44 additions & 32 deletions docs/extended_data_message.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,34 @@ Code examples can be found in [`extended_data_message.examples.cpp`](extended_da

Extended Data Messages are represented by a

struct extended_data_message : universal_packet
{
explicit extended_data_message(status_t);
};
```cpp
struct extended_data_message : universal_packet
{
explicit extended_data_message(status_t);
};
```

Usually one will not use this class directly, but instead

struct sysex8_packet : extended_data_message
{
sysex8_packet(status_t, uint8_t stream_id, group_t);
```cpp
struct sysex8_packet : extended_data_message
{
sysex8_packet(status_t, uint8_t stream_id, group_t);

packet_format format() const;
packet_format format() const;

uint8_t stream_id() const;
void set_stream_id(uint8_t);
uint8_t stream_id() const;
void set_stream_id(uint8_t);

uint8_t payload_byte(size_t b) const;
void set_payload_byte(size_t, uint8_t);
uint8_t payload_byte(size_t b) const;
void set_payload_byte(size_t, uint8_t);

size_t payload_size() const;
void set_payload_size(size_t);
size_t payload_size() const;
void set_payload_size(size_t);

void add_payload_byte(uint8_t);
};
void add_payload_byte(uint8_t);
};
```

A `sysex8_packet` can hold a payload of up to 13 bytes and provides APIs to add or read the payload bytes.
System Exclusive 8 packets payload is allowed to be 8 bit, different to traditional MIDI System Exclusive (7 bit).
Expand All @@ -38,37 +42,45 @@ In MIDI 2 is allowed to have multiple parallel System Exclusive 8 streams runnin

Instead of using sysex8_packet constructors one can create messages using factory functions:

sysex8_packet make_sysex8_complete_packet(uint8_t stream_id, group_t);
sysex8_packet make_sysex8_start_packet(uint8_t stream_id, group_t);
sysex8_packet make_sysex8_continue_packet(uint8_t stream_id, group_t);
sysex8_packet make_sysex8_end_packet(uint8_t stream_id, group_t);
```cpp
sysex8_packet make_sysex8_complete_packet(uint8_t stream_id, group_t);
sysex8_packet make_sysex8_start_packet(uint8_t stream_id, group_t);
sysex8_packet make_sysex8_continue_packet(uint8_t stream_id, group_t);
sysex8_packet make_sysex8_end_packet(uint8_t stream_id, group_t);
```

Filtering of Extended Data Messages can be done checking `universal_packet::type()` against
`packet_type::extended_data` or use

bool is_extended_data_message(const universal_packet&);
bool is_sysex8_packet(const universal_packet&);
```cpp
bool is_extended_data_message(const universal_packet&);
bool is_sysex8_packet(const universal_packet&);
```

### SysEx8 Packet View

Once validated being a `sysex8` packet one can create a `sysex8_packet_view`
for a `universal_packet`:

struct sysex8_packet_view
{
explicit sysex8_packet_view(const universal_packet&);
```cpp
struct sysex8_packet_view
{
explicit sysex8_packet_view(const universal_packet&);

group_t group() const;
packet_format format() const;
uint8_t stream_id() const;
size_t payload_size() const;
uint8_t payload_byte(size_t b) const;
};
group_t group() const;
packet_format format() const;
uint8_t stream_id() const;
size_t payload_size() const;
uint8_t payload_byte(size_t b) const;
};
```

View members provide accessors to the properties of the message.

The additional

std::optional<sysex8_packet_view> as_sysex8_packet_view(const universal_packet&);
```cpp
std::optional<sysex8_packet_view> as_sysex8_packet_view(const universal_packet&);
```

helper allows to combine packet type check and view creation in a single statement.
Loading