Files
wedding-phone/test_complete.py
grabowski 80c45389b2 Add rotary phone web interface with multiple greeting support
Features:
- Web interface for managing rotary phone system
- Support for multiple greeting messages with selector
- Direct audio playback in browser for recordings and greetings
- Upload multiple WAV files at once
- Set active greeting that plays when phone is picked up
- HiFiBerry DAC+ADC Pro audio configuration
- GPIO-based handset detection and audio recording
- Real-time status monitoring with auto-refresh

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 14:37:20 +07:00

284 lines
8.1 KiB
Python

#!/usr/bin/env python3
"""
Complete HiFiBerry Test - Verify speaker and microphone work
"""
import pyaudio
import wave
import numpy as np
import time
import os
# HiFiBerry device index (from your system)
HIFIBERRY_INDEX = 1
SAMPLE_RATE = 44100
def test_playback():
"""Test speaker output"""
print("\n" + "="*60)
print("🔊 TESTING SPEAKER PLAYBACK")
print("="*60)
audio = pyaudio.PyAudio()
try:
# Show device info
info = audio.get_device_info_by_index(HIFIBERRY_INDEX)
print(f"\nUsing device: {info['name']}")
print(f"Max output channels: {info['maxOutputChannels']}")
# Generate test tone (440Hz A note)
print("\nGenerating 440Hz test tone...")
duration = 3
t = np.linspace(0, duration, int(SAMPLE_RATE * duration), False)
tone = np.sin(2 * np.pi * 440 * t)
tone = (tone * 0.3 * 32767).astype(np.int16) # 30% volume
# Open stream
stream = audio.open(
format=pyaudio.paInt16,
channels=1,
rate=SAMPLE_RATE,
output=True,
output_device_index=HIFIBERRY_INDEX,
frames_per_buffer=1024
)
print("🎵 Playing 3-second tone - LISTEN NOW!")
print(" You should hear a clear beep from your speaker...")
# Play
chunk_size = 2048
for i in range(0, len(tone.tobytes()), chunk_size):
stream.write(tone.tobytes()[i:i + chunk_size])
stream.stop_stream()
stream.close()
print("✓ Playback completed")
return True
except Exception as e:
print(f"❌ Playback error: {e}")
return False
finally:
audio.terminate()
def test_recording():
"""Test microphone input"""
print("\n" + "="*60)
print("🎙️ TESTING MICROPHONE RECORDING")
print("="*60)
audio = pyaudio.PyAudio()
try:
# Show device info
info = audio.get_device_info_by_index(HIFIBERRY_INDEX)
print(f"\nUsing device: {info['name']}")
print(f"Max input channels: {info['maxInputChannels']}")
# Record
print("\n🔴 Recording for 5 seconds...")
print(" SPEAK NOW or make noise near the microphone...")
stream = audio.open(
format=pyaudio.paInt16,
channels=1,
rate=SAMPLE_RATE,
input=True,
input_device_index=HIFIBERRY_INDEX,
frames_per_buffer=1024
)
frames = []
for i in range(0, int(SAMPLE_RATE / 1024 * 5)):
data = stream.read(1024, exception_on_overflow=False)
frames.append(data)
stream.stop_stream()
stream.close()
print("✓ Recording completed")
# Save to file
filename = "/tmp/test_recording.wav"
wf = wave.open(filename, 'wb')
wf.setnchannels(1)
wf.setsampwidth(audio.get_sample_size(pyaudio.paInt16))
wf.setframerate(SAMPLE_RATE)
wf.writeframes(b''.join(frames))
wf.close()
print(f"✓ Saved to {filename}")
# Calculate volume level
audio_data = np.frombuffer(b''.join(frames), dtype=np.int16)
volume = np.abs(audio_data).mean()
max_volume = np.abs(audio_data).max()
print(f"\nRecording analysis:")
print(f" Average level: {volume:.0f}")
print(f" Peak level: {max_volume}")
if max_volume > 1000:
print(" ✓ Good signal detected!")
else:
print(" ⚠️ Very low signal - microphone might not be working")
audio.terminate()
# Play back
print("\n🔊 Playing back your recording...")
audio = pyaudio.PyAudio()
wf = wave.open(filename, 'rb')
stream = audio.open(
format=audio.get_format_from_width(wf.getsampwidth()),
channels=wf.getnchannels(),
rate=wf.getframerate(),
output=True,
output_device_index=HIFIBERRY_INDEX
)
data = wf.readframes(1024)
while data:
stream.write(data)
data = wf.readframes(1024)
stream.stop_stream()
stream.close()
wf.close()
print("✓ Playback of recording completed")
print(f"\nYou can listen again with: aplay {filename}")
return True
except Exception as e:
print(f"❌ Recording error: {e}")
return False
finally:
audio.terminate()
def test_dial_tone():
"""Test classic dial tone (350Hz + 440Hz)"""
print("\n" + "="*60)
print("📞 TESTING DIAL TONE")
print("="*60)
audio = pyaudio.PyAudio()
try:
print("\nGenerating classic dial tone (350Hz + 440Hz)...")
duration = 3
t = np.linspace(0, duration, int(SAMPLE_RATE * duration), False)
# Generate two frequencies
tone1 = np.sin(2 * np.pi * 350 * t)
tone2 = np.sin(2 * np.pi * 440 * t)
tone = (tone1 + tone2) / 2
tone = (tone * 0.3 * 32767).astype(np.int16)
stream = audio.open(
format=pyaudio.paInt16,
channels=1,
rate=SAMPLE_RATE,
output=True,
output_device_index=HIFIBERRY_INDEX,
frames_per_buffer=1024
)
print("🎵 Playing dial tone - This is what you'll hear when picking up the phone!")
chunk_size = 2048
for i in range(0, len(tone.tobytes()), chunk_size):
stream.write(tone.tobytes()[i:i + chunk_size])
stream.stop_stream()
stream.close()
print("✓ Dial tone playback completed")
return True
except Exception as e:
print(f"❌ Dial tone error: {e}")
return False
finally:
audio.terminate()
def show_device_info():
"""Show all audio devices"""
print("\n" + "="*60)
print("📋 AUDIO DEVICES ON YOUR SYSTEM")
print("="*60)
audio = pyaudio.PyAudio()
print("\nAll devices:")
for i in range(audio.get_device_count()):
info = audio.get_device_info_by_index(i)
device_type = []
if info['maxOutputChannels'] > 0:
device_type.append("OUTPUT")
if info['maxInputChannels'] > 0:
device_type.append("INPUT")
marker = " ← USING THIS" if i == HIFIBERRY_INDEX else ""
print(f" [{i}] {info['name']}{marker}")
print(f" Type: {', '.join(device_type)}")
print(f" Sample rate: {info['defaultSampleRate']}")
print()
audio.terminate()
def main():
"""Main test routine"""
print("\n" + "="*60)
print("🎛️ HIFIBERRY COMPLETE SYSTEM TEST")
print("="*60)
print(f"\nTesting HiFiBerry at device index: {HIFIBERRY_INDEX}")
# Show devices
show_device_info()
input("\nPress Enter to start tests...")
# Test 1: Playback
test1 = test_playback()
time.sleep(1)
# Test 2: Dial tone
test2 = test_dial_tone()
time.sleep(1)
# Test 3: Recording
test3 = test_recording()
# Summary
print("\n" + "="*60)
print("📊 TEST SUMMARY")
print("="*60)
print(f"\n✓ Speaker playback: {'PASS ✓' if test1 else 'FAIL ❌'}")
print(f"✓ Dial tone: {'PASS ✓' if test2 else 'FAIL ❌'}")
print(f"✓ Microphone recording: {'PASS ✓' if test3 else 'FAIL ❌'}")
if test1 and test2 and test3:
print("\n🎉 ALL TESTS PASSED!")
print("\nYour rotary phone system is ready to use!")
print("Run: python3 rotary_phone_web.py")
else:
print("\n⚠️ Some tests failed. Check the output above for details.")
print("\n" + "="*60)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\nTest interrupted by user")
except Exception as e:
print(f"\n❌ Error: {e}")
import traceback
traceback.print_exc()