draw midi input indicator
This commit is contained in:
parent
5320e14745
commit
e97dc5695f
|
|
@ -74,6 +74,26 @@ impl MidiInputManager {
|
||||||
// Get all available MIDI input ports
|
// Get all available MIDI input ports
|
||||||
let ports = midi_in.ports();
|
let ports = midi_in.ports();
|
||||||
|
|
||||||
|
// Get list of currently available device names
|
||||||
|
let mut available_devices = Vec::new();
|
||||||
|
for port in &ports {
|
||||||
|
if let Ok(port_name) = midi_in.port_name(port) {
|
||||||
|
available_devices.push(port_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove disconnected devices from our connections list
|
||||||
|
{
|
||||||
|
let mut conns = connections.lock().unwrap();
|
||||||
|
let before_count = conns.len();
|
||||||
|
conns.retain(|conn| available_devices.contains(&conn.device_name));
|
||||||
|
let after_count = conns.len();
|
||||||
|
|
||||||
|
if before_count != after_count {
|
||||||
|
println!("MIDI: Removed {} disconnected device(s)", before_count - after_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get list of already connected device names
|
// Get list of already connected device names
|
||||||
let connected_devices: Vec<String> = {
|
let connected_devices: Vec<String> = {
|
||||||
let conns = connections.lock().unwrap();
|
let conns = connections.lock().unwrap();
|
||||||
|
|
|
||||||
22
src/main.js
22
src/main.js
|
|
@ -1306,6 +1306,28 @@ async function handleAudioEvent(event) {
|
||||||
context.pianoRedraw();
|
context.pianoRedraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Update MIDI activity timestamp
|
||||||
|
context.lastMidiInputTime = Date.now();
|
||||||
|
console.log('[NoteOn] Set lastMidiInputTime to:', context.lastMidiInputTime);
|
||||||
|
|
||||||
|
// Start animation loop to keep redrawing the MIDI indicator
|
||||||
|
if (!context.midiIndicatorAnimating) {
|
||||||
|
context.midiIndicatorAnimating = true;
|
||||||
|
const animateMidiIndicator = () => {
|
||||||
|
if (context.timelineWidget && context.timelineWidget.requestRedraw) {
|
||||||
|
context.timelineWidget.requestRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep animating for 1 second after last MIDI input
|
||||||
|
const elapsed = Date.now() - context.lastMidiInputTime;
|
||||||
|
if (elapsed < 1000) {
|
||||||
|
requestAnimationFrame(animateMidiIndicator);
|
||||||
|
} else {
|
||||||
|
context.midiIndicatorAnimating = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
requestAnimationFrame(animateMidiIndicator);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'NoteOff':
|
case 'NoteOff':
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ export let context = {
|
||||||
recordingTrackId: null,
|
recordingTrackId: null,
|
||||||
recordingClipId: null,
|
recordingClipId: null,
|
||||||
playPauseButton: null, // Reference to play/pause button for updating appearance
|
playPauseButton: null, // Reference to play/pause button for updating appearance
|
||||||
|
// MIDI activity indicator
|
||||||
|
lastMidiInputTime: 0, // Timestamp (Date.now()) of last MIDI input
|
||||||
};
|
};
|
||||||
|
|
||||||
// Application configuration
|
// Application configuration
|
||||||
|
|
|
||||||
|
|
@ -799,6 +799,56 @@ class TimelineWindowV2 extends Widget {
|
||||||
ctx.fillText(typeText, typeX, y + this.trackHierarchy.trackHeight / 2)
|
ctx.fillText(typeText, typeX, y + this.trackHierarchy.trackHeight / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Draw MIDI activity indicator for active MIDI track
|
||||||
|
if (track.type === 'audio' && track.object && track.object.type === 'midi') {
|
||||||
|
|
||||||
|
if (this.context && this.context.lastMidiInputTime > 0) {
|
||||||
|
|
||||||
|
// Check if this is the selected/active MIDI track
|
||||||
|
const isActiveMidiTrack = isSelected && track.object && track.object.audioTrackId !== undefined
|
||||||
|
|
||||||
|
|
||||||
|
if (isActiveMidiTrack) {
|
||||||
|
const elapsed = Date.now() - this.context.lastMidiInputTime
|
||||||
|
const fadeTime = 1000 // Fade out over 1 second (increased for visibility)
|
||||||
|
|
||||||
|
if (elapsed < fadeTime) {
|
||||||
|
// const mindicatorSize = 12 // Made larger
|
||||||
|
// const mindicatorX = this.trackHeaderWidth - 35 // Position to the left of buttons
|
||||||
|
// const mindicatorY = y + this.trackHierarchy.trackHeight / 2
|
||||||
|
|
||||||
|
// console.log(`[MIDI mIndicator] Drawing at (${mindicatorX}, ${mindicatorY}) with alpha ${1}`)
|
||||||
|
|
||||||
|
// // Draw pulsing circle with border
|
||||||
|
// ctx.strokeStyle = `rgba(0, 255, 0, ${1})`
|
||||||
|
// ctx.fillStyle = `rgba(0, 255, 0, ${1 * 0.5})`
|
||||||
|
// ctx.lineWidth = 2
|
||||||
|
// ctx.beginPath()
|
||||||
|
// ctx.arc(mindicatorX, mindicatorY, mindicatorSize / 2, 0, Math.PI * 2)
|
||||||
|
// ctx.fill()
|
||||||
|
// ctx.stroke()
|
||||||
|
|
||||||
|
const alpha = Math.max(0.2, 1 - (elapsed / fadeTime)) // Minimum alpha of 0.3 for visibility
|
||||||
|
const indicatorSize = 10
|
||||||
|
const indicatorX = this.trackHeaderWidth - 35 // Position to the left of buttons
|
||||||
|
const indicatorY = y + this.trackHierarchy.trackHeight / 2
|
||||||
|
|
||||||
|
console.log(`[MIDI Indicator] Drawing at (${indicatorX}, ${indicatorY}) with alpha ${alpha}`)
|
||||||
|
|
||||||
|
// Draw pulsing circle with border
|
||||||
|
ctx.strokeStyle = `rgba(0, 255, 0, ${alpha})`
|
||||||
|
ctx.fillStyle = `rgba(0, 255, 0, ${alpha})`
|
||||||
|
ctx.lineWidth = 2
|
||||||
|
ctx.beginPath()
|
||||||
|
ctx.arc(indicatorX, indicatorY, indicatorSize / 2, 0, Math.PI * 2)
|
||||||
|
ctx.fill()
|
||||||
|
ctx.stroke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Draw toggle buttons for object/shape/audio/midi tracks (Phase 3)
|
// Draw toggle buttons for object/shape/audio/midi tracks (Phase 3)
|
||||||
if (track.type === 'object' || track.type === 'shape' || track.type === 'audio' || track.type === 'midi') {
|
if (track.type === 'object' || track.type === 'shape' || track.type === 'audio' || track.type === 'midi') {
|
||||||
const buttonSize = 14
|
const buttonSize = 14
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue