jdxi_editor.ui.editors.io.player

MIDI Player for JDXI Editor

Attributes

QApplication

QObject

Signal

Slot

Classes

MidiFileEditor

Midi File Editor

Module Contents

jdxi_editor.ui.editors.io.player.QApplication = None[source]
jdxi_editor.ui.editors.io.player.QObject = None[source]
jdxi_editor.ui.editors.io.player.Signal = None[source]
jdxi_editor.ui.editors.io.player.Slot = None[source]
class jdxi_editor.ui.editors.io.player.MidiFileEditor(midi_helper: jdxi_editor.midi.io.helper.MidiIOHelper | None = None, parent: PySide6.QtWidgets.QWidget = None, preset_helper: jdxi_editor.jdxi.preset.helper.JDXiPresetHelper = None)[source]

Bases: jdxi_editor.ui.editors.synth.editor.SynthEditor

Midi File Editor

BUFFER_WINDOW_SECONDS = 30.0[source]
_last_position_label = None[source]
parent = None[source]
preset_helper = None[source]
profiler = None[source]
midi_state[source]
midi_playback_worker[source]
midi_total_ticks = None[source]
midi_port[source]
current_tempo_bpm = None[source]
midi_preferred_channels[source]
usb_recorder[source]
ui[source]
midi_timer_init()[source]

Initialize or reinitialize the MIDI playback timer. Ensures previous connections are safely removed.

ui_ensure_timer_connected()[source]

ui_ensure_timer_connected

Returns:

Ensure the midi_play_next_event is connected to midi.timer.timeout

ui_init()[source]

Initialize the UI for the MidiPlayer.

init_ruler() PySide6.QtWidgets.QWidget[source]

init_ruler

Returns:

QWidget

init_midi_file_controls() PySide6.QtWidgets.QHBoxLayout[source]

init_midi_file_controls

Returns:

QHBoxLayout

init_automation_controls() PySide6.QtWidgets.QHBoxLayout[source]

Create simple automation controls to insert Program Changes at the current position.

populate_automation_programs(source: str) None[source]

Populate the program combo based on source list. source: “Digital” | “Analog” | “Drums”

on_automation_type_changed(_: int) None[source]

Handle automation type selection change.

insert_program_change_current_position() None[source]

Insert Bank Select (CC#0, CC#32) and Program Change at the current slider time.

_find_track_for_channel(channel: int) int[source]
_insert_messages_at_abs_tick(track: mido.MidiTrack, abs_tick_target: int, new_msgs: list[mido.Message]) None[source]

Insert a list of messages at a given absolute tick, preserving delta times.

init_usb_port_controls() PySide6.QtWidgets.QHBoxLayout[source]

init_usb_port_controls

Returns:

init_usb_file_controls() PySide6.QtWidgets.QHBoxLayout[source]

init_usb_file_controls

Returns:

QHBoxLayout

generate_auto_wav_filename() str | None[source]

Generate an automatic WAV filename based on current date/time and MIDI file name.

Returns:

Generated filename path or None if no MIDI file is loaded

update_auto_wav_filename() None[source]

Update the WAV filename automatically if auto-generate is enabled.

on_usb_file_auto_generate_toggled(state: PySide6.QtCore.Qt.CheckState)[source]

on_usb_file_auto_generate_toggled

Parameters:

state – Qt.CheckState

Returns:

on_usb_file_output_name_changed(state: PySide6.QtCore.Qt.CheckState)[source]

on_usb_file_output_name_changed

Parameters:

state – Qt.CheckState

Returns:

init_transport_controls() PySide6.QtWidgets.QGroupBox[source]

init_transport_controls

Returns:

None

update_tempo_us_from_worker(tempo_us: int) None[source]

update_tempo_us_from_worker

Parameters:

tempo_us – int tempo in microseconds e.g 500_000

Returns:

None

update_playback_worker_tempo_us(tempo_us: int) None[source]

update_playback_worker_tempo_us

Parameters:

tempo_us – tempo in microseconds e.g 500_000

Returns:

None

setup_worker()[source]

setup_worker

Returns:

None

Setup the worker and thread for threaded playback using QTimer

midi_playback_worker_stop()[source]

midi_playback_worker_stop

Returns:

None

on_suppress_program_changes_toggled(state: PySide6.QtCore.Qt.CheckState) None[source]

on_suppress_program_changes_toggled

Parameters:

state – Qt.CheckState

Returns:

None

on_suppress_control_changes_toggled(state: PySide6.QtCore.Qt.CheckState)[source]

on_suppress_control_changes_toggled

Parameters:

state – Qt.CheckState

Returns:

on_usb_save_recording_toggled(state: PySide6.QtCore.Qt.CheckState)[source]

on_usb_save_recording_toggled

Parameters:

state – Qt.CheckState

Returns:

usb_populate_devices() list[source]

usb_populate_devices

usb port selection

Returns:

list List of USB devices

usb_port_jdxi_auto_connect(usb_devices: list) None[source]

usb_port_jdxi_auto_connect

Parameters:

usb_devices – list

Returns:

None

Auto-select the first matching device

usb_start_recording(recording_rate: int = pyaudio.paInt16)[source]

usb_start_recording

Parameters:

recording_rate – int

Returns:

None

Start recording in a separate thread

usb_select_recording_file()[source]

Open a file picker dialog to select output .wav file.

midi_save_file() None[source]

midi_save_file

Returns:

None

Save the current MIDI file to disk.

midi_load_file() None[source]

Load a MIDI file and initialize parameters

midi_load_file_from_path(file_path: str) None[source]

Load a MIDI file from a given path and initialize parameters.

Parameters:

file_path – Path to the MIDI file

calculate_tick_duration()[source]

calculate_tick_duration

Returns:

Calculate the duration of a single MIDI tick in seconds.

calculate_duration() None[source]

calculate_duration

Returns:

None

Accurate Total Duration Calculation

midi_channel_select() None[source]

midi_channel_select

Returns:

None

Select a suitable MIDI channel for playback - detects a “reasonable” playback channel

midi_extract_events() None[source]

midi_extract_events

Returns:

None

Extract events from the MIDI file and store them in the midi_state.

detect_initial_tempo() dict[int, int][source]

detect_initial_tempo

Returns:

dict[int, int]

Detect Initial Tempo from the UI

ui_display_set_tempo_usecs(tempo_usecs: int) None[source]

ui_display_set_tempo_usecs

Parameters:

tempo_usecs – int tempo in microseconds

Returns:

None

Set the tempo in the UI and log it.

set_display_tempo_bpm(tempo_bpm: float) None[source]

set_display_tempo_bpm

Parameters:

tempo_bpm – int tempo in microseconds

Returns:

None

Set the tempo in the UI and log it.

update_upper_display_with_tempo_and_bar(elapsed_time: float | None = None) None[source]

Update the upper display with tempo and optionally bar number.

Parameters:

elapsed_time – Optional elapsed time for bar calculation. If None, uses current playback state.

turn_off_effects() None[source]

Turn off all effects (Effect 1, Effect 2, Delay, Reverb) when starting playback. This prevents distortion and other effects from being accidentally enabled.

midi_playback_start()[source]

Start playback of the MIDI file from the beginning (or resume if paused).

setup_playback_worker()[source]

setup_playback_worker

Returns:

None

Setup the MIDI playback worker (prepare buffered messages, etc.)

start_playback_worker()[source]

start_playback_worker

Returns:

None

Start the timer for actual playback.

setup_and_start_playback_worker()[source]

setup_and_start_playback_worker

Returns:

None

Setup the MIDI playback worker and start the timer.

initialize_midi_state() None[source]

Initialize muted tracks, muted channels, and buffered messages.

calculate_start_tick() int | None[source]

Calculate the start tick based on elapsed playback time. :return: Start tick or None if an error occurs.

is_track_muted(track_index: int) bool[source]

is_track_muted

Parameters:

track_index – Index of the track to check.

Returns:

True if the track is muted, otherwise False.

Check if the track is muted.

is_channel_muted(channel_index: int) bool[source]

is_channel_muted

Parameters:

channel_index – Index of the track to check.

Returns:

True if the channel is muted, otherwise False.

Check if the channel is muted.

handle_set_tempo(msg: mido.Message, absolute_time_ticks: int) None[source]

handle_set_tempo

Parameters:
  • absolute_time_ticks – int

  • msg – The MIDI message to process.

Handle ‘set_tempo’ messages in a MIDI track.

buffer_message(absolute_time_ticks: int, msg: mido.Message) None[source]

Add a MIDI message to the buffer. :param absolute_time_ticks: Absolute tick of the message. :param msg: The MIDI message to buffer.

buffer_message_with_tempo(absolute_time_ticks: int, msg: mido.Message, tempo: int) None[source]

Add a MIDI message to the buffer with a specific tempo. :param absolute_time_ticks: Absolute tick of the message. :param msg: The MIDI message to buffer. :param tempo: The tempo that was active when this message was created.

midi_message_buffer_refill() None[source]

midi_message_buffer_refill

Returns:

None

Preprocess MIDI tracks into a sorted list of (absolute_ticks, raw_bytes, tempo) tuples. Meta messages are excluded except for set_tempo.

process_tracks(start_tick: int) None[source]

process_tracks

Parameters:

start_tick – int

Returns:

process_track_messages(start_tick: int, track: mido.MidiTrack) None[source]

process_track_messages

Parameters:
  • start_tick – int The starting tick from which to begin processing.

  • track – mido.MidiTrack The MIDI track to process.

Returns:

None

Process messages in a MIDI track from a given starting tick.

get_muted_tracks()[source]

get_muted_tracks

Returns:

None

Get the muted tracks from the MIDI track viewer.

get_muted_channels()[source]

get_muted_channels

Returns:

None

Get the muted channels from the MIDI track viewer.

on_tempo_usecs_changed(tempo: int)[source]

on_tempo_usecs_changed

Parameters:

tempo – int

Returns:

None

on_tempo_bpm_changed(bpm: float)[source]

on_tempo_bpm_changed

Parameters:

bpm – float

Returns:

None

midi_play_next_event()[source]

UI update: Update slider and label to reflect playback progress.

ui_midi_file_position_slider_set_position(elapsed_time: float) None[source]

ui.midi_file_position_slider_set_position

Parameters:

elapsed_time – float

Returns:

None

Update the slider position and label based on elapsed time.

midi_scrub_position()[source]

Updates the MIDI playback state based on the scrub position.

is_midi_ready() bool[source]

Checks if the MIDI file and events are available.

stop_playback() None[source]

Stops playback and resets the paused state.

get_target_time() float[source]

Retrieves the target time from the slider and logs it.

update_event_index(target_time: float) None[source]

Finds and updates the event index based on the target time.

update_playback_start_time(target_time: float) None[source]

Adjusts the playback start time based on the scrub position.

stop_all_notes() None[source]

Sends Control Change 123 and note_off messages to silence all notes.

prepare_for_playback() None[source]

Clears the event buffer and starts the playback worker.

midi_stop_playback()[source]

Stops playback and resets everything to the beginning.

stop_playback_worker()[source]

Stops and disconnects the playback worker.

reset_midi_state()[source]

Resets MIDI state variables.

reset_tempo()[source]

Resets the tempo to the initial value.

clear_active_notes() None[source]

Clears the active notes.

log_event_buffer() None[source]

log_event_buffer

Returns:

None

Logs the event buffer for debugging.

perform_profiling() None[source]

perform_profiling

Returns:

None

Performs profiling and logs the results.

midi_play_next_event_disconnect() None[source]

midi_play_next_event_disconnect

Returns:

None

Disconnect the midi_play_next_event from the timer’s timeout signal.

midi_playback_worker_disconnect() None[source]

midi_playback_worker_disconnect

Returns:

None

Disconnect the midi_playback_worker.do_work from the timer’s timeout signal.

ui_position_slider_reset() None[source]

position_slider_reset

Returns:

None

Reset the position slider and label to initial state.

ui_position_label_update_time(time_seconds: float | None = None) None[source]

ui_position_label_update_time

Parameters:

time_seconds – float, optional

Returns:

None

calculate_current_bar(elapsed_time: float | None = None) float | None[source]

Calculate the current bar number based on elapsed playback time.

Parameters:

elapsed_time – Optional elapsed time in seconds. If None, calculates from current playback state.

Returns:

Current bar number (1-based) or None if calculation fails.

ui_position_label_set_time(elapsed_time: float | None = None) None[source]

Update the position label with formatted elapsed time and total duration. Caps elapsed_time to total duration to prevent overflow display. Also updates the bar number in the DigitalTitle upper display.

midi_playback_pause_toggle()[source]

midi_playback_pause_toggle

Returns:

None

Toggle pause and resume playback.

midi_playback_worker_handle_result(result=None)[source]

Handle the result from the worker. This can be used to update the UI or perform further actions. :param result: The result from the worker

_print_segment_statistics()[source]

Print segment statistics for the buffered MIDI file.

_fix_buffer_tempo_assignments()[source]

Fix tempo assignments in the buffer - each message should use the tempo that was active at its tick.

_notify_pattern_sequencer_file_loaded() None[source]

Notify Pattern Sequencer that a MIDI file has been loaded.