jdxi_editor.ui.editors.midi_player.editor
MIDI Player for JDXI Editor
Attributes
Classes
Midi File Attributes |
|
Midi File Editor |
Module Contents
- class jdxi_editor.ui.editors.midi_player.editor.MidiFilePlayer(midi_helper: jdxi_editor.midi.io.helper.MidiIOHelper | None = None, parent: jdxi_editor.ui.common.QWidget = None, preset_helper: jdxi_editor.ui.preset.helper.JDXiPresetHelper = None)[source]
Bases:
jdxi_editor.ui.editors.synth.editor.SynthEditorMidi File Editor
- preset_helper: jdxi_editor.ui.preset.helper.JDXiPresetHelper = None[source]
- midi_file_group: jdxi_editor.ui.widgets.midi_file_group.MidiFileGroup[source]
- event_suppression_group: jdxi_editor.ui.widgets.event_suppression_group.EventSuppressionGroup[source]
- classification_group: jdxi_editor.ui.widgets.classification_group.ClassificationGroup[source]
- mute_channels_group: jdxi_editor.ui.widgets.mute_channels_group.MuteChannelsGroup[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
- detect_and_assign_drum_tracks() None[source]
Detect drum tracks in the loaded MIDI file and assign Channel 10 (1-based) to them.
This analyzes all tracks using heuristics and automatically sets the channel spinboxes for tracks identified as drum tracks.
- _classify_tracks(drum_indices: list[int])[source]
Classify non-drum tracks into Bass, Keys/Guitars, Strings.
- _handle_unclassified_tracks(classifications, updated: dict[str, list[str]])[source]
Handle unclassified
- _has_classified_tracks(updated_tracks: dict) bool[source]
Return True if at least one track was classified (excluding unclassified).
- _build_classification_message(updated: dict[str, list[str]]) str[source]
build classification message
- init_automation_usb_grid() PySide6.QtWidgets.QGridLayout[source]
Create a grid layout containing Automation, USB Port, and USB File controls.
- insert_program_change_current_position() None[source]
Insert Bank Select (CC#0, CC#32) and Program Change at the current slider time.
- _build_message(message_type: str, channel: int, value: int = None, program: int = None) mido.Message[source]
Build message
- _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.
- _toggle_channel_mute(channel: int, is_muted: bool, btn) None[source]
Toggle mute state for a specific MIDI channel. Updates both the track viewer and the player’s muted channels state.
- Parameters:
channel – int MIDI channel (1-16)
is_muted – bool is the channel muted?
- _sync_mute_buttons_from_track_viewer() None[source]
Sync mute channel buttons in the USB file controls with the track viewer’s state. Called when MIDI file is loaded or track viewer’s mute state changes.
- apply_all_track_changes() None[source]
Apply all Track Name and MIDI Channel changes. Calls the track viewer’s apply_all_track_changes method.
- apply_channel_presets() None[source]
Send live MIDI Program Changes to the synth and insert presets into the MIDI file. Ch 1→Picked Bass, Ch 2→Piano, Ch 3→JP8 Strings.
- _create_transport_control(spec: picomidi.ui.widget.transport.spec.TransportSpec, layout: PySide6.QtWidgets.QHBoxLayout, button_group: PySide6.QtWidgets.QButtonGroup | None) None[source]
Create a transport button + label row
- 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
- 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:
- 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_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 from the file and set midi_state.tempo_initial.
- Returns:
dict[track_number, tempo_usec] for tracks that have set_tempo
- 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 – float tempo in BPM
- Returns:
None
Set the tempo in the UI and log it. Also pushes tempo to Pattern Sequencer so both editors stay in sync when using the same playback pipeline.
- update_upper_display_with_tempo_and_bar(elapsed_time: float | None = None) None[source]
Update the upper digital 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.) Loads engine and wires on_event; worker uses engine.process_until_now().
- 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.
- 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
- 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.
- 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. Uses target_time (slider value in seconds) directly so elapsed_time matches the scrubbed position and advances correctly during playback.
- log_event_buffer() None[source]
log_event_buffer
- Returns:
None
Logs the event buffer for debugging.
- perform_profiling() None[source]
No-op: per-playback profiling was removed to avoid skewing app-wide profiles.
- 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.
- midi_file_position_label_update_time(time_seconds: float | None = None) None[source]
midi_file_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 digital. Also updates the bar number in the DigitalTitle upper digital.
- 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
- _get_pattern_sequencer_editor()[source]
Return the Pattern Sequencer editor instance if available, else None.
- _push_tempo_to_pattern_sequencer(tempo_bpm: float) None[source]
Push current display tempo to Pattern Sequencer so it stays in sync with playback pipeline.
- _notify_pattern_sequencer_file_loaded() None[source]
Notify Pattern Sequencer that a MIDI file has been loaded.