RX24-Mini-Project-Code / timing_generator.py
timing_generator.py
Raw
# ================================================================================
# Timing Generator
# Use to manually create a timing array for synchronizing LED brightness to audio dialogue.
# ================================================================================
# Release Version: 2025.1.0
# Initial code generated by Claude Sonnet 4 on 2025-08-10 
# ================================================================================

import time
import keyboard
import threading

# Configuration
output_filename = "test.tim"  # Output timing file
max_brightness = 255         # Peak brightness for syllables
baseline_brightness = 50     # Baseline brightness between syllables

class TimingRecorder:
    def __init__(self):
        self.events = []
        self.start_time = None
        self.recording = False
        
    def countdown_timer(self):
        """Added by Claude: 5-second countdown timer that prints every 0.1 seconds"""
        print("\n๐Ÿ• Starting 5-second countdown...")
        for i in range(50, 0, -1):  # Added by Claude: Count from 50 to 1 (5.0 to 0.1 seconds)
            remaining_time = i / 10.0  # Added by Claude: Convert to decimal seconds
            print(f"\rโณ {remaining_time:.1f} seconds remaining...", end='', flush=True)  # Added by Claude: Print countdown with carriage return
            time.sleep(0.1)  # Added by Claude: Wait 0.1 seconds between updates
        
        print("\n๐ŸŽฌ GO! Start tapping for syllables!\n")  # Added by Claude: Signal that countdown is complete
        
    def start_recording(self):
        """Start timing recording"""
        print("=== Audio Timing Recorder ===")
        print("Instructions:")
        print("1. Press ENTER to start recording")
        print("2. Play your audio file")
        print("3. Press SPACEBAR, N, or M on each syllable/word")  # Modified by Claude: Updated instructions for new trigger keys
        print("4. Press ESC when done")
        print()
        
        input("Press ENTER to start recording...")
        
        print(f"\n๐Ÿ”ด RECORDING STARTED")
        
        # Added by Claude: Call the countdown timer function BEFORE setting start_time
        self.countdown_timer()
        
        # Fixed by Claude: Set start_time AFTER countdown to prevent 5-second offset
        self.start_time = time.time()
        self.recording = True
        
        print("Play your audio now!")
        print("Tap SPACEBAR, N, or M for each syllable")  # Modified by Claude: Updated instruction for new trigger keys
        print("Press ESC to stop\n")
        
        # Add baseline event at start
        self.events.append((0, baseline_brightness))
        
    def add_event(self):
        """Add timing event when spacebar is pressed"""
        if not self.recording:
            return
            
        current_time = time.time()
        elapsed_ms = int((current_time - self.start_time) * 1000)
        
        # Add peak brightness event
        self.events.append((elapsed_ms, max_brightness))
        print(f"โšก Syllable at {elapsed_ms}ms")
        
        # Schedule baseline event 200ms later (adjust this timing as needed)
        fade_delay = 200
        self.events.append((elapsed_ms + fade_delay, baseline_brightness))
        
    def stop_recording(self):
        """Stop recording and save file"""
        if not self.recording:
            return
            
        self.recording = False
        print(f"\n๐ŸŸข RECORDING STOPPED")
        
        # Sort events by timestamp
        self.events.sort()
        
        # Save to file
        with open(output_filename, 'w') as f:
            for timestamp, brightness in self.events:
                f.write(f"{timestamp},{brightness}\n")
        
        print(f"๐Ÿ“ Saved {len(self.events)} events to {output_filename}")
        self.print_summary()
        
    def print_summary(self):
        """Print recording summary"""
        if not self.events:
            return
            
        duration = self.events[-1][0] / 1000.0
        syllable_count = len([e for e in self.events if e[1] == max_brightness])
        
        print(f"\nRecording Summary:")
        print(f"Duration: {duration:.1f} seconds")
        print(f"Syllables: {syllable_count}")
        print(f"Events: {len(self.events)}")
        print(f"\nFile ready for ESP32!")

def main():
    recorder = TimingRecorder()
    
    # Start recording
    recorder.start_recording()
    
    try:
        while recorder.recording:
            # Wait for key presses
            event = keyboard.read_event()
            
            if event.event_type == keyboard.KEY_DOWN:
                if event.name in ['space', 'n', 'm']:  # Modified by Claude: Added 'n' and 'm' as trigger keys along with spacebar
                    recorder.add_event()
                elif event.name == 'esc':
                    recorder.stop_recording()
                    break
                    
    except KeyboardInterrupt:
        recorder.stop_recording()

if __name__ == "__main__":
    main()