Source code for jdxi_editor.midi.sysex.request.factory

"""
This module contains constants, functions, and logic to generate and compute
Roland JD-Xi SysEx messages for requesting program and tone names.

It defines a set of SysEx constants specific to the JD-Xi and provides the
following functionality:

1. **Constants**: A dictionary `SYSEX_CONSTANTS` containing key constants
   required to construct the SysEx messages, including the JD-Xi header,
   tone areas, and other necessary fields.
2. **Checksum Calculation**: A function `roland_checksum` that computes the
   Roland checksum for a given SysEx data string. This checksum is used
   to ensure the integrity of the message.
3. **Request Generation**: A function `create_request` that dynamically generates
   a SysEx message based on the header, tone area, and parameters provided.
4. **Program and Tone Requests**: A list `PROGRAM_AND_TONE_NAME_REQUESTS`
   containing pre-generated SysEx requests for various program and tone areas
   like digital, analog, and drums.

SysEx message format includes:
- Start byte `F0`, end byte `F7`
- JD-Xi specific header and command information
- Roland checksum for data integrity

Functions:
- `roland_checksum(data: str) -> str`: Computes and returns the Roland checksum
  based on the input SysEx data string.
- `create_request(header, tone_area, param1) -> str`: Constructs a complete
  SysEx request message, appends the checksum, and returns the full message.

    Examples
    --------
    To generate a request for the program common area:

    >>> request = create_request(
    ...     TEMPORARY_PROGRAM_RQ11_HEADER,
    ...     SYSEX_CONSTANTS['PROGRAM_COMMON_AREA'],
    ...     "00 00 00 00 00 40"
    )

    To retrieve a list of all program and tone name requests:
    all_requests = PROGRAM_AND_TONE_NAME_REQUESTS
"""

from enum import Enum
from typing import Union

from jdxi_editor.midi.sysex.request.hex import JDXISysExHex


[docs] def roland_checksum(data: str) -> str: """ Compute Roland checksum for a given SysEx data string (space-separated hex). """ byte_values = [int(x, 16) for x in data.split()] checksum = (128 - (sum(byte_values) % 128)) % 128 return f"{checksum:02X}"
[docs] def create_request(header: str, temp_area: Union[str, JDXISysExHex], part: str) -> str: """ Create a SysEx request string using header, area, parameter, and Roland checksum. """ temp_area_str = temp_area.value if isinstance(temp_area, Enum) else temp_area data = f"{temp_area_str} {part}" checksum = roland_checksum(data) return f"{header} {data} {checksum} {JDXISysExHex.END}"