# 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 ```bash 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: ```bash 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) ```bash # 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 ```bash 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: ```bash chmod +x configure_hifiberry.sh ./configure_hifiberry.sh ``` Or follow the manual instructions in `AUDIO_FIX.md`. ### 5. Create Configuration File Copy the example configuration and customize it: ```bash cp config.example.json config.json nano config.json # or use your preferred editor ``` **Important settings to configure:** ```json { "gpio": { "hook_pin": 17, // GPIO pin for hookswitch "hook_pressed_state": "LOW" // "LOW" or "HIGH" }, "audio": { "device_index": 1, // HiFiBerry device index "sample_rate": 44100 }, "paths": { "base_dir": "./rotary_phone_data" // Relative or absolute path }, "web": { "port": 8080 } } ``` **Finding your audio device index:** ```bash 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())]" ``` ### 6. Test Your Audio ```bash python3 test_complete.py ``` This will test: - Speaker playback - Dial tone generation - Microphone recording ### 7. Run the System ```bash python3 rotary_phone_web.py ``` The web interface will be available at: - `http://localhost:8080` - `http://: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 1. **Guest picks up phone**: System detects via GPIO 2. **Greeting plays**: Active greeting message plays through speaker 3. **Recording starts**: After greeting, system records guest message 4. **Guest hangs up**: Recording stops and saves automatically 5. **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 ├── config.example.json # Example configuration (copy to config.json) ├── 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) ``` rotary_phone_data/ # Default location (configurable) ├── recordings/ # Voice recordings from guests ├── sounds/ # Greeting message WAV files └── user_config.json # Runtime settings (volume, active greeting) ``` ## Configuration All configuration is done via the `config.json` file. **No need to edit Python code!** ### Configuration File Structure The `config.json` file contains all system settings: ```json { "gpio": { "hook_pin": 17, // GPIO pin number for hookswitch "hook_pressed_state": "LOW" // "LOW" or "HIGH" depending on switch }, "audio": { "device_index": 1, // Audio device index (run test to find) "chunk_size": 1024, // Audio buffer size "format": "paInt16", // Audio format (16-bit) "channels": 1, // Mono audio "sample_rate": 44100, // 44.1kHz sample rate "max_record_seconds": 300 // Max recording time (5 minutes) }, "paths": { "base_dir": "./rotary_phone_data", // Data directory (relative or absolute) "recordings_dir": "recordings", // Subdirectory for recordings "sounds_dir": "sounds" // Subdirectory for greeting sounds }, "web": { "port": 8080, // Web interface port "max_upload_size_mb": 50 // Max upload file size }, "system": { "active_greeting": "dialtone.wav", // Default greeting "volume": 70 // Default volume (0-100) } } ``` ### Finding Your Audio Device To find your HiFiBerry or other audio device index: ```bash 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())]" ``` Look for your HiFiBerry device and note its index number, then set it in `config.json`. ## Troubleshooting ### No Sound from Speaker 1. Check HiFiBerry configuration: ```bash aplay -l # List audio devices amixer -c 3 sset Digital 100% # Set volume (adjust card number) ``` 2. Test speaker directly: ```bash speaker-test -D plughw:3,0 -c 1 -t wav ``` 3. Run the complete test: ```bash python3 test_complete.py ``` ### Microphone Not Recording 1. Check microphone is connected to HiFiBerry input 2. Adjust input gain: ```bash alsamixer -c 3 ``` 3. Test recording: ```bash arecord -D plughw:3,0 -f cd test.wav -d 5 aplay test.wav ``` ### GPIO Not Detecting Hookswitch 1. Verify GPIO pin number in `config.json` 2. Check if switch is normally open or closed 3. Update `hook_pressed_state` in `config.json` ("LOW" or "HIGH") 4. Test with a simple script: ```python 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 1. Check if Flask is running: `ps aux | grep python` 2. Verify port in `config.json` matches URL 3. Check firewall: `sudo ufw allow 8080` (or your configured port) 4. Check IP address: `hostname -I` 5. Try localhost: `http://127.0.0.1:8080` ### Configuration Errors If the script won't start: 1. Ensure `config.json` exists (copy from `config.example.json`) 2. Validate JSON syntax: `python3 -m json.tool config.json` 3. Check all paths exist or can be created 4. Verify audio device index is correct ## Auto-start on Boot Create a systemd service: ```bash sudo nano /etc/systemd/system/wedding-phone.service ``` Add (replace `/path/to/wedding-phone` with your actual path): ```ini [Unit] Description=Wedding Phone Service After=network.target sound.target [Service] Type=simple User=pi WorkingDirectory=/path/to/wedding-phone ExecStart=/usr/bin/python3 /path/to/wedding-phone/rotary_phone_web.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target ``` Enable and start: ```bash 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 interface - `GET /api/status` - Phone status JSON - `GET /api/recordings` - List all recordings - `GET /api/greetings` - List all greeting messages - `GET /api/volume` - Get current volume setting - `POST /api/volume` - Set volume level (0-100) - `POST /upload_greeting` - Upload new greeting - `POST /set_active_greeting` - Set active greeting - `POST /delete_greeting/` - Delete greeting - `GET /play_audio//` - Stream audio file - `GET /download/` - Download recording - `POST /delete/` - Delete recording - `POST /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.