Source code for jdxi_editor.jdxi.preset.data

"""
Module: preset_data

This module defines the `JDXIPresetData` class, which provides methods to retrieve
structured preset data for different JD-Xi synth types, including Analog, Digital1,
Digital2, and Drum. It calculates MIDI bank and program values for use in MIDI Program
Change messages.

Classes:
    - JDXIPresetData: Provides static methods for looking up JD-Xi presets by synth type
      and index.

Constants and Enums (from imports):
    - JDXISynth: Enum representing synth types (ANALOG, DIGITAL_1, DIGITAL_2, DRUM).
    - JDXIPresets: Named preset lists for each synth type.

Example usage:
=============
>>>from jdxi_editor.jdxi.synth.type import JDXISynth
...preset_data = JDXIPresetData.get_preset_details(JDXISynth.DIGITAL_1, 10)
...print(preset_data)
    # Output:
    # {
    #     'presets': [...],
    #     'bank_msb': 1,
    #     'bank_lsb': 0,
    #     'program': 10
    # }
>>>import json
...from dataclasses import asdict
...
...preset = JDXiPresetData.get_preset_details(JDXiSynth.ANALOG_SYNTH, 5)
...
...with open("preset.json", "w") as f:
...    json.dump(asdict(preset), f, indent=2)
...
...with open("preset.json", "r") as f:
...    data = json.load(f)
...    preset = JDXiPresetData(**data)
"""

from dataclasses import asdict, dataclass
from typing import List, Optional

from decologr import Decologr as log

from jdxi_editor.jdxi.preset.lists import JDXiPresetToneList
from jdxi_editor.jdxi.synth.type import JDXiSynth


@dataclass
[docs] class JDXiPresetData:
[docs] name: str
[docs] presets: List[str]
[docs] bank_msb: int
[docs] bank_lsb: int
[docs] program: int
@staticmethod
[docs] def from_dict(data: dict) -> "JDXiPresetData": return JDXiPresetData( name=data.get("name", "Unnamed"), presets=data.get("presets", []), bank_msb=data.get("bank_msb", 0), bank_lsb=data.get("bank_lsb", 0), program=data.get("program", 0), )
@staticmethod
[docs] def get_preset_details(synth_type: str, preset_number: int) -> "JDXiPresetData": if synth_type == JDXiSynth.ANALOG_SYNTH: presets = JDXiPresetToneList.ANALOG bank_msb = 0x10 # JD-Xi MSB for Analog (example) bank_lsb = preset_number // 7 program = preset_number % 7 elif synth_type == JDXiSynth.DIGITAL_SYNTH_1: presets = JDXiPresetToneList.DIGITAL_ENUMERATED bank_msb = 0x10 bank_lsb = preset_number // 16 program = preset_number % 16 elif synth_type == JDXiSynth.DIGITAL_SYNTH_2: presets = JDXiPresetToneList.DIGITAL_ENUMERATED bank_msb = 0x10 bank_lsb = preset_number // 16 program = preset_number % 16 elif synth_type == JDXiSynth.DRUM_KIT: presets = JDXiPresetToneList.DRUM_ENUMERATED bank_msb = 0x10 bank_lsb = preset_number // 16 program = preset_number % 16 else: raise ValueError(f"Unknown synth type: {synth_type}") # Make sure preset_number is within range try: name = presets[preset_number] except IndexError: name = f"Unknown {synth_type} preset {preset_number}" return JDXiPresetData( name=name, presets=presets, bank_msb=bank_msb, bank_lsb=bank_lsb, program=program, )
[docs] def to_dict(self): return { "name": self.name, # "presets": self.presets, "bank_msb": self.bank_msb, "bank_lsb": self.bank_lsb, "program": self.program, }