You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

268 lines
8.7 KiB

#!/usr/bin/env python3
"""
Audio and MIDI Diagnostic Tool
Helps identify issues with audio playback and MIDI output
"""
import sys
import os
import time
# Add project to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def test_pygame_audio():
"""Test pygame audio system directly"""
print("=== Testing Pygame Audio ===")
try:
import pygame
import numpy as np
# Initialize pygame mixer
pygame.mixer.pre_init(frequency=22050, size=-16, channels=2, buffer=512)
pygame.mixer.init()
print("PASS: Pygame mixer initialized successfully")
# Test basic audio playback
print("Testing basic audio generation...")
# Generate a simple sine wave (440 Hz for 1 second)
sample_rate = 22050
duration = 1.0 # seconds
frequency = 440 # A4
# Generate samples
samples = np.sin(2 * np.pi * frequency * np.linspace(0, duration, int(sample_rate * duration)))
# Apply envelope and scale
envelope = np.exp(-np.linspace(0, 3, len(samples))) # Fade out
samples = samples * envelope * 0.5
# Convert to 16-bit integers and make stereo
samples = (samples * 32767).astype(np.int16)
stereo_samples = np.column_stack((samples, samples))
# Create and play sound
sound = pygame.sndarray.make_sound(stereo_samples)
print("Playing test tone (440Hz for 1 second)...")
sound.play()
# Wait for playback
time.sleep(1.2)
print("✓ Direct pygame audio test completed")
return True
except Exception as e:
print(f"✗ Pygame audio test failed: {e}")
import traceback
traceback.print_exc()
return False
def test_simulator_audio():
"""Test the simulator audio system"""
print("\n=== Testing Simulator Audio ===")
try:
from simulator.simulator_engine import SimulatorEngine
simulator = SimulatorEngine()
print(f"✓ Simulator initialized, audio enabled: {simulator.audio_enabled}")
print(f" Audio initialized: {simulator.audio_initialized_flag}")
print(f" Stereo mode: {getattr(simulator, 'stereo_mode', 'Unknown')}")
# Test note playback
print("Testing note playback through simulator...")
simulator.play_note(1, 60, 80) # Channel 1, Middle C, velocity 80
time.sleep(0.8)
simulator.stop_note(1, 60)
print("✓ Simulator audio test completed")
return True
except Exception as e:
print(f"✗ Simulator audio test failed: {e}")
import traceback
traceback.print_exc()
return False
def test_midi_devices():
"""Test MIDI device detection"""
print("\n=== Testing MIDI Devices ===")
try:
import mido
print("✓ Mido library available")
# List MIDI outputs
outputs = mido.get_output_names()
print(f"Available MIDI outputs ({len(outputs)}):")
for i, output in enumerate(outputs):
print(f" {i+1}. {output}")
if outputs:
print(f"\nTesting MIDI output with: {outputs[0]}")
try:
midi_out = mido.open_output(outputs[0])
print("✓ MIDI output opened successfully")
# Send test note
print("Sending test note (Middle C)...")
msg_on = mido.Message('note_on', channel=0, note=60, velocity=80)
msg_off = mido.Message('note_off', channel=0, note=60, velocity=0)
midi_out.send(msg_on)
print(" - Note ON sent")
time.sleep(0.5)
midi_out.send(msg_off)
print(" - Note OFF sent")
midi_out.close()
print("✓ MIDI test completed")
return True
except Exception as e:
print(f"✗ MIDI output test failed: {e}")
return False
else:
print("⚠ No MIDI outputs available")
return False
except ImportError:
print("✗ Mido library not available")
return False
except Exception as e:
print(f"✗ MIDI test failed: {e}")
return False
def test_arpeggiator_integration():
"""Test the full arpeggiator system"""
print("\n=== Testing Arpeggiator Integration ===")
try:
from core.midi_channel_manager import MIDIChannelManager
from core.volume_pattern_engine import VolumePatternEngine
from core.synth_router import SynthRouter
from simulator.simulator_engine import SimulatorEngine
from core.output_manager import OutputManager
from core.arpeggiator_engine import ArpeggiatorEngine
# Create components
channel_manager = MIDIChannelManager()
volume_engine = VolumePatternEngine()
synth_router = SynthRouter(channel_manager)
simulator = SimulatorEngine()
output_manager = OutputManager(simulator)
arpeggiator = ArpeggiatorEngine(channel_manager, synth_router, volume_engine, output_manager)
print("✓ All components initialized")
# Test simulator mode
output_manager.set_mode("simulator")
print(f"✓ Output mode: {output_manager.current_mode}")
# Configure arpeggiator
arpeggiator.set_root_note(60) # Middle C
arpeggiator.set_scale("major")
arpeggiator.set_pattern_type("up")
arpeggiator.set_tempo(120)
# Add notes to trigger arpeggiator
print("Adding notes and starting arpeggiator...")
arpeggiator.note_on(60) # C
arpeggiator.note_on(64) # E
# Start arpeggiator
started = arpeggiator.start()
print(f"✓ Arpeggiator started: {started}")
if started:
print("Letting arpeggiator run for 3 seconds...")
time.sleep(3)
arpeggiator.stop()
print("✓ Arpeggiator stopped")
return True
except Exception as e:
print(f"✗ Arpeggiator integration test failed: {e}")
import traceback
traceback.print_exc()
return False
def test_system_audio():
"""Test system audio capabilities"""
print("\n=== Testing System Audio ===")
try:
import pygame
# Get mixer info
pygame.mixer.init()
print(f"✓ Pygame version: {pygame.version.ver}")
# Check mixer settings
freq = pygame.mixer.get_init()
if freq:
print(f"✓ Mixer frequency: {freq[0]}Hz, {freq[1]}-bit, {freq[2]} channels")
else:
print("✗ Mixer not initialized")
# Check number of channels
channels = pygame.mixer.get_num_channels()
print(f"✓ Available sound channels: {channels}")
return True
except Exception as e:
print(f"✗ System audio test failed: {e}")
return False
def main():
"""Run all diagnostic tests"""
print("MIDI Arpeggiator - Audio & MIDI Diagnostics")
print("=" * 50)
results = {}
# Run tests
results['system_audio'] = test_system_audio()
results['pygame_audio'] = test_pygame_audio()
results['simulator_audio'] = test_simulator_audio()
results['midi_devices'] = test_midi_devices()
results['arpeggiator'] = test_arpeggiator_integration()
# Summary
print("\n" + "=" * 50)
print("DIAGNOSTIC SUMMARY:")
print("=" * 50)
for test_name, result in results.items():
status = "✓ PASS" if result else "✗ FAIL"
print(f"{test_name:20}: {status}")
# Recommendations
print("\nRECOMMENDATIONS:")
print("-" * 30)
if not results['pygame_audio']:
print("• Audio issues detected - check Windows audio settings")
print("• Try different audio drivers or devices")
print("• Check if other applications are using audio exclusively")
if not results['midi_devices']:
print("• No MIDI devices found for hardware mode")
print("• Install virtual MIDI cables (like loopMIDI) for software synths")
print("• Check MIDI device drivers")
if not results['simulator_audio']:
print("• Simulator audio not working - check pygame audio initialization")
if not results['arpeggiator']:
print("• Arpeggiator integration issues - check component initialization")
print(f"\nOverall success rate: {sum(results.values())}/{len(results)} tests passed")
if __name__ == "__main__":
main()