Features: - Add pyproject.toml for UV package management - Volume control with real-time slider (0-100%) - Backend volume adjustment with numpy audio scaling - Volume setting persists in config.json - Debounced API calls for smooth slider interaction - Enhanced audio playback with volume multiplier - Update README with UV installation instructions - Add volume control documentation API Changes: - GET /api/volume - Get current volume setting - POST /api/volume - Set volume level 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Wedding Phone - Vintage Rotary Phone Audio System
A Raspberry Pi-based rotary phone system for weddings and events. Guests can pick up the handset to hear custom greeting messages and leave voice recordings. Features a modern web interface for managing messages and recordings.
Features
- Vintage Phone Integration: Uses a real rotary phone with GPIO hook detection
- Custom Greeting Messages: Upload multiple greeting messages and select which one plays
- Voice Recording: Automatically records guest messages after the greeting
- Web Interface: Beautiful, responsive web UI for managing the system
- Audio Playback: Play recordings and greetings directly in the browser
- Volume Control: Adjust playback volume with real-time slider (0-100%)
- Multiple Message Support: Upload and manage multiple greeting messages
- Active Message Selector: Choose which greeting plays when the phone is picked up
- HiFiBerry Support: Optimized for HiFiBerry DAC+ADC Pro audio quality
- Real-time Status: Monitor phone status (on-hook/off-hook/recording)
- Auto-refresh: Status updates every 5 seconds
Hardware Requirements
- Raspberry Pi (3/4/5 or Zero 2 W)
- HiFiBerry DAC+ADC Pro (or similar audio interface)
- Vintage rotary phone with hookswitch
- Speaker (connected to HiFiBerry output)
- Microphone (connected to HiFiBerry input, or use phone handset mic)
Software Requirements
- Raspberry Pi OS (Bullseye or newer)
- Python 3.7+
- Required Python packages:
- pyaudio
- flask
- numpy
- RPi.GPIO
- wave (built-in)
Installation
1. Clone the Repository
git clone https://git.b4l.co.th/grabowski/wedding-phone.git
cd wedding-phone
2. Install UV (Recommended)
UV is a fast Python package installer and resolver. Install it:
curl -LsSf https://astral.sh/uv/install.sh | sh
# Or on Raspberry Pi with pip:
pip3 install uv
3. Install Dependencies
Option A: Using UV (Recommended)
# Install system dependencies
sudo apt-get update
sudo apt-get install -y python3-pyaudio portaudio19-dev
# Install Python dependencies with UV
uv pip install -e .
Option B: Using pip
sudo apt-get update
sudo apt-get install -y python3-pip python3-pyaudio portaudio19-dev
pip3 install flask numpy RPi.GPIO
4. Configure HiFiBerry
Run the automatic configuration script:
chmod +x configure_hifiberry.sh
./configure_hifiberry.sh
Or follow the manual instructions in AUDIO_FIX.md.
5. Test Your Audio
python3 test_complete.py
This will test:
- Speaker playback
- Dial tone generation
- Microphone recording
6. Configure GPIO Pin
Edit rotary_phone_web.py and set your hookswitch GPIO pin:
HOOK_PIN = 17 # Change to your GPIO pin number
HOOK_PRESSED = GPIO.LOW # Or GPIO.HIGH depending on your switch
7. Run the System
python3 rotary_phone_web.py
The web interface will be available at:
http://localhost:8080http://<raspberry-pi-ip>:8080
Usage
Web Interface
The web interface provides four main sections:
1. Phone Status
- Shows current phone state (on-hook/off-hook/recording)
- Displays active recording filename
- Auto-refreshes every 5 seconds
2. Volume Control
- Adjust Volume: Drag slider to set playback volume (0-100%)
- Real-time visual feedback with percentage display
- Changes apply immediately to greeting playback
- Volume setting persists across restarts
3. Greeting Messages
- Upload: Click "Choose WAV File(s)" to upload one or multiple greeting messages
- Play: Click "▶️ Play" to preview any greeting in your browser
- Set Active: Click "⭐ Set Active" to select which greeting plays when the phone is picked up
- Delete: Remove unwanted greetings (cannot delete the active one)
- Default Tone: Generate a classic telephone dial tone
4. Recordings
- Play: Listen to recordings directly in the browser
- Download: Save recordings to your computer
- Delete: Remove unwanted recordings
- Statistics: View total recordings, storage used, and total duration
Phone Operation
- Guest picks up phone: System detects via GPIO
- Greeting plays: Active greeting message plays through speaker
- Recording starts: After greeting, system records guest message
- Guest hangs up: Recording stops and saves automatically
- Ready for next call: System returns to waiting state
File Structure
wedding-phone/
├── rotary_phone_web.py # Main application
├── test_complete.py # Audio testing script
├── configure_hifiberry.sh # HiFiBerry setup script
├── pyproject.toml # UV/pip package configuration
├── AUDIO_FIX.md # Audio configuration guide
├── README.md # This file
├── .gitignore # Git ignore rules
└── templates/ # Auto-generated on first run
└── index.html # Web interface (embedded in script)
Runtime Data (Auto-created)
/home/berwn/rotary_phone_data/
├── recordings/ # Voice recordings from guests
├── sounds/ # Greeting message WAV files
└── config.json # Active greeting configuration
Configuration
Audio Settings
Edit these constants in rotary_phone_web.py:
CHUNK = 1024 # Audio buffer size
FORMAT = pyaudio.paInt16 # 16-bit audio
CHANNELS = 1 # Mono
RATE = 44100 # 44.1kHz sample rate
RECORD_SECONDS = 300 # Max recording time (5 minutes)
HiFiBerry Device Index
If your HiFiBerry is at a different device index:
# Line ~103 and ~138 in rotary_phone_web.py
output_device_index=1, # Change this number
input_device_index=1, # Change this number
Find your device index:
python3 -c "import pyaudio; p=pyaudio.PyAudio(); [print(f'{i}: {p.get_device_info_by_index(i)[\"name\"]}') for i in range(p.get_device_count())]"
Web Server Port
WEB_PORT = 8080 # Change to your preferred port
Troubleshooting
No Sound from Speaker
-
Check HiFiBerry configuration:
aplay -l # List audio devices amixer -c 3 sset Digital 100% # Set volume (adjust card number) -
Test speaker directly:
speaker-test -D plughw:3,0 -c 1 -t wav -
Run the complete test:
python3 test_complete.py
Microphone Not Recording
- Check microphone is connected to HiFiBerry input
- Adjust input gain:
alsamixer -c 3 - Test recording:
arecord -D plughw:3,0 -f cd test.wav -d 5 aplay test.wav
GPIO Not Detecting Hookswitch
- Verify GPIO pin number
- Check if switch is normally open or closed
- Test with a simple script:
import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_UP) print(GPIO.input(17)) # Should change when switch toggles
Web Interface Not Accessible
- Check if Flask is running:
ps aux | grep python - Verify firewall:
sudo ufw allow 8080 - Check IP address:
hostname -I - Try localhost:
http://127.0.0.1:8080
Auto-start on Boot
Create a systemd service:
sudo nano /etc/systemd/system/wedding-phone.service
Add:
[Unit]
Description=Wedding Phone Service
After=network.target sound.target
[Service]
Type=simple
User=berwn
WorkingDirectory=/home/berwn/wedding-phone
ExecStart=/usr/bin/python3 /home/berwn/wedding-phone/rotary_phone_web.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable wedding-phone.service
sudo systemctl start wedding-phone.service
sudo systemctl status wedding-phone.service
API Endpoints
The system provides REST API endpoints:
GET /- Web interfaceGET /api/status- Phone status JSONGET /api/recordings- List all recordingsGET /api/greetings- List all greeting messagesGET /api/volume- Get current volume settingPOST /api/volume- Set volume level (0-100)POST /upload_greeting- Upload new greetingPOST /set_active_greeting- Set active greetingPOST /delete_greeting/<filename>- Delete greetingGET /play_audio/<type>/<filename>- Stream audio fileGET /download/<filename>- Download recordingPOST /delete/<filename>- Delete recordingPOST /restore_default_sound- Generate default dial tone
Contributing
Feel free to open issues or submit pull requests for improvements.
License
This project is open source and available for personal and commercial use.
Credits
Created for wedding events to capture guest messages in a unique, nostalgic way.
Support
For issues or questions, please open an issue on the repository.