Implemented automatic config file updates to add missing settings with default values on startup. This eliminates manual config editing when upgrading to newer versions. Features: - Auto-updates config.json with missing settings - Auto-updates user_config.json with missing user preferences - Console logging shows which settings were added - Preserves existing values - only adds missing keys - Writes updated config back to file automatically - Graceful error handling if write fails System config (config.json): - Comprehensive defaults for all sections - GPIO, audio, paths, backup, web, system settings - New settings like volume_greeting, volume_button, volume_beep User config (user_config.json): - Loop-based checking against default_config - Automatic save when updates are detected - Error logging for troubleshooting Benefits: - Seamless upgrades without manual config edits - No breaking changes when new features are added - Users see exactly what was added in console - Backward compatible with old config files Example console output: [CONFIG] Added missing setting: system.volume_beep = 70 [CONFIG] Updated config.json with missing defaults [USER_CONFIG] Added missing setting: volume_button = 70 [USER_CONFIG] Updated user_config.json with missing defaults Updated README.md to document auto-update feature. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
755 lines
22 KiB
Markdown
755 lines
22 KiB
Markdown
# 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.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# 1. Clone and enter directory
|
|
git clone https://git.b4l.co.th/grabowski/wedding-phone.git
|
|
cd wedding-phone
|
|
|
|
# 2. Install UV package manager
|
|
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
|
|
# 3. Create config from example
|
|
cp config.example.json config.json
|
|
nano config.json # Edit GPIO pins and audio device
|
|
|
|
# 4. Install dependencies
|
|
make sync
|
|
|
|
# 5. Configure HiFiBerry (if using)
|
|
./configure_hifiberry.sh
|
|
|
|
# 6. Test audio
|
|
make test
|
|
|
|
# 7. Run the system
|
|
make start
|
|
|
|
# 8. Optional: Install as service for auto-start
|
|
./install_service.sh
|
|
|
|
# 9. Optional: Setup USB backup
|
|
sudo ./setup_usb.sh
|
|
```
|
|
|
|
Web interface available at: `http://<raspberry-pi-ip>:8080`
|
|
|
|
## Table of Contents
|
|
|
|
- [Quick Start](#quick-start)
|
|
- [Features](#features)
|
|
- [Hardware Requirements](#hardware-requirements)
|
|
- [Software Requirements](#software-requirements)
|
|
- [Installation](#installation)
|
|
- [Running the System](#running-the-system)
|
|
- [Usage](#usage)
|
|
- [Web Interface](#web-interface)
|
|
- [Phone Operation](#phone-operation)
|
|
- [Extra Button](#extra-button-operation-optional)
|
|
- [Greeting Delay](#greeting-delay-optional)
|
|
- [USB Backup](#usb-backup-optional)
|
|
- [Configuration](#configuration)
|
|
- [Systemd Service](#install-as-system-service-optional)
|
|
- [Troubleshooting](#troubleshooting)
|
|
- [API Endpoints](#api-endpoints)
|
|
- [File Structure](#file-structure)
|
|
- [Contributing](#contributing)
|
|
- [License](#license)
|
|
|
|
## 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
|
|
- **Extra Button Support**: Optional GPIO button to play custom sounds during recording
|
|
- **USB Backup**: Automatic backup to multiple USB drives with CRC32 verification
|
|
- **Data Integrity**: Every file write is verified with CRC checksums
|
|
- **HiFiBerry Support**: Optimized for HiFiBerry DAC+ADC Pro audio quality
|
|
- **Production-Ready**: Uses Waitress WSGI server for stable, production-grade web serving
|
|
- **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.8+ (required for Flask 2.3+)
|
|
- UV package manager (recommended) or pip
|
|
- Make (for simplified commands)
|
|
- Required Python packages:
|
|
- flask>=2.3.0
|
|
- numpy>=1.21.0
|
|
- pyaudio>=0.2.13
|
|
- RPi.GPIO>=0.7.1
|
|
- waitress>=2.1.0 (production WSGI server)
|
|
- scipy>=1.7.0 (audio resampling utility)
|
|
|
|
## 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
|
|
make sync
|
|
# Or manually:
|
|
# uv pip install flask numpy pyaudio RPi.GPIO waitress
|
|
```
|
|
|
|
#### 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 waitress
|
|
```
|
|
|
|
### 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"
|
|
"extra_button_enabled": true, // Enable extra button feature
|
|
"extra_button_pin": 27, // GPIO pin for extra button
|
|
"extra_button_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
|
|
|
|
#### Option A: Using Make (Recommended)
|
|
|
|
```bash
|
|
# Run the wedding phone system
|
|
make start
|
|
|
|
# Or run the audio test
|
|
make test
|
|
```
|
|
|
|
#### Option B: Using UV Directly
|
|
|
|
```bash
|
|
# Run the wedding phone system
|
|
uv run python rotary_phone_web.py
|
|
|
|
# Or run the audio test
|
|
uv run python test_complete.py
|
|
```
|
|
|
|
#### Option C: Run with Python
|
|
|
|
```bash
|
|
python3 rotary_phone_web.py
|
|
```
|
|
|
|
The web interface will be available at:
|
|
- `http://localhost:8080`
|
|
- `http://<raspberry-pi-ip>:8080`
|
|
|
|
### 8. Install as System Service (Optional)
|
|
|
|
To run the wedding phone automatically on boot:
|
|
|
|
```bash
|
|
# Run the installer script
|
|
./install_service.sh
|
|
```
|
|
|
|
The installer will:
|
|
- Check dependencies
|
|
- Install the systemd service
|
|
- Configure for your user and project path
|
|
- Optionally enable and start the service
|
|
|
|
**Manual service commands:**
|
|
|
|
```bash
|
|
# Enable service to start on boot
|
|
sudo systemctl enable wedding-phone
|
|
|
|
# Start service now
|
|
sudo systemctl start wedding-phone
|
|
|
|
# Stop service
|
|
sudo systemctl stop wedding-phone
|
|
|
|
# Restart service
|
|
sudo systemctl restart wedding-phone
|
|
|
|
# View logs (live)
|
|
sudo journalctl -u wedding-phone -f
|
|
|
|
# View status
|
|
sudo systemctl status wedding-phone
|
|
|
|
# Disable service
|
|
sudo systemctl disable wedding-phone
|
|
```
|
|
|
|
## 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
|
|
- **Set Button**: Click "🔘 Set Button" to assign sound to extra button (if enabled)
|
|
- **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 individual recordings to your computer
|
|
- **Download All**: Download all recordings as a single ZIP file with timestamp
|
|
- **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
|
|
|
|
### Extra Button Operation (Optional)
|
|
|
|
If enabled in `config.json`:
|
|
1. **Guest picks up phone**: Phone goes off-hook, greeting plays
|
|
2. **Recording starts**: After greeting finishes
|
|
3. **Guest presses button**: System detects GPIO signal (only works during recording)
|
|
4. **Sound plays**: Configured button sound plays through speaker
|
|
5. **Can be pressed multiple times**: Works throughout the recording phase
|
|
6. **Debounced**: 0.5s delay prevents accidental double-presses
|
|
|
|
**Note:** Button only responds during the recording phase (not during greeting or when on-hook)
|
|
|
|
### Greeting Delay (Optional)
|
|
|
|
Configure a delay before the greeting plays:
|
|
- Set `greeting_delay_seconds` in `config.json` (0-10 seconds)
|
|
- Useful for giving guests a moment after picking up
|
|
- Example: 2 second delay gives time to position the phone
|
|
- Default: 0 (greeting plays immediately)
|
|
|
|
### USB Backup (Optional)
|
|
|
|
Automatically backup all recordings and greeting files to USB drives:
|
|
|
|
**Configuration** (`config.json`):
|
|
```json
|
|
{
|
|
"backup": {
|
|
"enabled": true,
|
|
"usb_paths": [
|
|
"/media/usb0",
|
|
"/media/usb1"
|
|
],
|
|
"verify_crc": true,
|
|
"backup_on_write": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Features:**
|
|
- **Multiple USB Drives**: Backup to one or more USB drives simultaneously
|
|
- **CRC32 Verification**: Every backup is verified with CRC checksum
|
|
- **Automatic Backup**: Files are backed up immediately after recording/upload
|
|
- **Integrity Check**: Corrupted backups are automatically deleted
|
|
- **Web Monitoring**: View USB drive status, free space, and test backups
|
|
|
|
**Web Interface:**
|
|
- Monitor USB drive status (mounted, writable, free space)
|
|
- Test backup functionality with one click
|
|
- View real-time backup results
|
|
- Green = Ready, Yellow = Not Writable, Red = Not Mounted
|
|
|
|
**Backup Structure:**
|
|
```
|
|
/media/usb0/
|
|
└── wedding-phone-backup/
|
|
├── recordings/
|
|
│ ├── recording_20250124_143022.wav
|
|
│ └── recording_20250124_143145.wav
|
|
└── sounds/
|
|
├── dialtone.wav
|
|
└── greeting.wav
|
|
```
|
|
|
|
**How It Works:**
|
|
1. Recording finishes or greeting uploaded
|
|
2. File saved to main storage
|
|
3. CRC32 checksum calculated for source file
|
|
4. File copied to each USB drive
|
|
5. CRC32 checksum verified on each copy
|
|
6. Corrupted copies deleted automatically
|
|
7. Success/failure logged to console
|
|
|
|
**Mount USB Drives with Proper Permissions:**
|
|
|
|
**Automated Setup (Easiest):**
|
|
```bash
|
|
# Run the interactive USB setup script
|
|
sudo ./setup_usb.sh
|
|
```
|
|
This interactive script will:
|
|
- Scan for all connected USB drives
|
|
- Let you select which drives to auto-mount
|
|
- Choose custom mount point names (e.g., usb0, usb1, backup)
|
|
- Create systemd auto-mount units
|
|
- Handle permissions automatically (uid/gid)
|
|
- Work even when USB drives are plugged in after boot
|
|
|
|
**Option 1: Mount with user permissions (Recommended)**
|
|
```bash
|
|
# Find your USB device
|
|
lsblk
|
|
|
|
# Create mount point
|
|
sudo mkdir -p /media/usb0
|
|
|
|
# Mount with user ownership (replace $USER with your username if needed)
|
|
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sda1 /media/usb0
|
|
|
|
# Verify it's writable
|
|
touch /media/usb0/test.txt && rm /media/usb0/test.txt
|
|
```
|
|
|
|
**Option 2: Auto-mount in /etc/fstab with user permissions**
|
|
```bash
|
|
# Get USB UUID
|
|
sudo blkid /dev/sda1
|
|
|
|
# Edit fstab
|
|
sudo nano /etc/fstab
|
|
|
|
# Add line (replace UUID and username):
|
|
UUID=XXXX-XXXX /media/usb0 vfat defaults,nofail,uid=1000,gid=1000 0 0
|
|
# Note: uid=1000 is usually the first user, check with: id -u
|
|
```
|
|
|
|
**Option 3: Change ownership after mounting**
|
|
```bash
|
|
# Mount normally
|
|
sudo mount /dev/sda1 /media/usb0
|
|
|
|
# Change ownership (replace with your username)
|
|
sudo chown -R $USER:$USER /media/usb0
|
|
```
|
|
|
|
**Quick Setup Script:**
|
|
```bash
|
|
#!/bin/bash
|
|
# setup_usb.sh - Mount USB drives with proper permissions
|
|
|
|
# Create mount points
|
|
sudo mkdir -p /media/usb0 /media/usb1
|
|
|
|
# Mount USB drives with user ownership
|
|
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sda1 /media/usb0
|
|
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sdb1 /media/usb1
|
|
|
|
echo "USB drives mounted!"
|
|
ls -la /media/usb0 /media/usb1
|
|
```
|
|
|
|
## File Structure
|
|
|
|
```
|
|
wedding-phone/
|
|
├── rotary_phone_web.py # Main application (Flask + GPIO + Audio)
|
|
├── test_complete.py # Audio testing script
|
|
├── configure_hifiberry.sh # HiFiBerry DAC+ADC setup script
|
|
├── install_service.sh # Systemd service installer (interactive)
|
|
├── setup_usb.sh # Interactive USB auto-mount setup (systemd)
|
|
├── wedding-phone.service # Systemd service file template
|
|
├── Makefile # Make commands (start, test, sync, clean)
|
|
├── config.example.json # Example configuration (copy to config.json)
|
|
├── pyproject.toml # Python package configuration
|
|
├── AUDIO_FIX.md # Audio troubleshooting guide
|
|
├── CHANGELOG.md # Version history and upgrade notes
|
|
├── README.md # This file (main documentation)
|
|
├── .gitignore # Git ignore rules
|
|
└── templates/ # Auto-generated on first run
|
|
└── index.html # Web interface (auto-generated from script)
|
|
```
|
|
|
|
**Note:** The `templates/index.html` file is automatically generated when you first run `rotary_phone_web.py`. If you update the script and want to regenerate the template with new features, simply delete the `templates` directory and restart the 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!**
|
|
|
|
### Auto-Update Feature
|
|
|
|
The system automatically adds missing configuration settings with default values when it starts:
|
|
|
|
- **config.json** - System configuration is auto-updated with any missing settings
|
|
- **user_config.json** - User settings are auto-updated with new defaults
|
|
- Console shows which settings were added: `[CONFIG] Added missing setting: system.volume_beep = 70`
|
|
- Original config is preserved - only missing keys are added
|
|
- No manual editing required when upgrading to newer versions
|
|
|
|
This means you can upgrade the code and your old config files will work automatically!
|
|
|
|
### 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
|
|
"extra_button_enabled": true, // Enable optional extra button
|
|
"extra_button_pin": 27, // GPIO pin for extra button
|
|
"extra_button_pressed_state": "LOW" // Button pressed state
|
|
},
|
|
"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": 48000, // 48kHz 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
|
|
},
|
|
"backup": {
|
|
"enabled": true, // Enable USB backup
|
|
"usb_paths": ["/media/usb0", "/media/usb1"], // USB mount points
|
|
"verify_crc": true, // Verify backups with CRC32
|
|
"backup_on_write": true // Backup immediately after write
|
|
},
|
|
"web": {
|
|
"port": 8080, // Web interface port
|
|
"max_upload_size_mb": 50 // Max upload file size
|
|
},
|
|
"system": {
|
|
"active_greeting": "dialtone.wav", // Default greeting
|
|
"extra_button_sound": "button_sound.wav", // Default button sound
|
|
"beep_sound": "beep.wav", // Recording start beep
|
|
"beep_enabled": true, // Enable beep before recording
|
|
"greeting_delay_seconds": 0, // Delay before greeting plays (0-10)
|
|
"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`
|
|
|
|
### Audio Sample Rate Mismatch
|
|
|
|
If you see errors like `Expression 'paInvalidSampleRate' failed` or warnings about sample rate mismatches:
|
|
|
|
1. **Check your config.json sample rate** (default is 48000Hz):
|
|
```json
|
|
"audio": {
|
|
"sample_rate": 48000
|
|
}
|
|
```
|
|
|
|
2. **Resample your audio files** to match the configured rate:
|
|
```bash
|
|
# Using the provided resampling script
|
|
python3 resample_audio.py
|
|
|
|
# Or manually with ffmpeg
|
|
ffmpeg -i input.wav -ar 48000 output.wav
|
|
```
|
|
|
|
3. **Delete default sounds** to regenerate at correct rate:
|
|
```bash
|
|
rm rotary_phone_data/sounds/dialtone.wav
|
|
rm rotary_phone_data/sounds/beep.wav
|
|
# These will be regenerated at startup
|
|
```
|
|
|
|
The `resample_audio.py` utility will:
|
|
- Automatically detect the target sample rate from `config.json`
|
|
- Create `.backup` files before modifying originals
|
|
- Resample all WAV files in the sounds directory
|
|
- Preserve stereo/mono and bit depth
|
|
|
|
### 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
|
|
|
|
## 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/<filename>` - Delete greeting
|
|
- `GET /play_audio/<type>/<filename>` - Stream audio file
|
|
- `GET /download/<filename>` - Download recording
|
|
- `GET /download_all` - Download all recordings as ZIP
|
|
- `POST /delete/<filename>` - Delete recording
|
|
- `POST /restore_default_sound` - Generate default dial tone
|
|
- `GET /api/backup/status` - Get USB backup drive status
|
|
- `POST /api/backup/test` - Test backup to all USB drives
|
|
- `GET /api/greeting_delay` - Get current greeting delay
|
|
- `POST /api/greeting_delay` - Set greeting delay (0-10 seconds)
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Here's how you can help:
|
|
|
|
1. **Report Bugs**: Open an issue describing the bug and how to reproduce it
|
|
2. **Suggest Features**: Open an issue describing your feature idea
|
|
3. **Submit Pull Requests**: Fork the repo, make changes, and submit a PR
|
|
4. **Improve Documentation**: Help make the docs clearer and more complete
|
|
5. **Share Your Experience**: Post photos/videos of your wedding phone setup!
|
|
|
|
### Development Guidelines
|
|
|
|
- Follow existing code style
|
|
- Test your changes thoroughly
|
|
- Update documentation for new features
|
|
- Add entries to CHANGELOG.md
|
|
- Use descriptive commit messages
|
|
|
|
## Version History
|
|
|
|
See [CHANGELOG.md](CHANGELOG.md) for detailed version history and upgrade notes.
|
|
|
|
**Current Version**: 1.2.0
|
|
|
|
**Major Updates:**
|
|
- ✅ USB backup with CRC verification
|
|
- ✅ Systemd service support
|
|
- ✅ UV package manager integration
|
|
- ✅ Greeting delay control
|
|
- ✅ Extra button support
|
|
- ✅ Immediate hook detection
|
|
- ✅ Configurable everything (no hardcoded paths)
|
|
|
|
## License
|
|
|
|
This project is open source and available for personal and commercial use.
|
|
|
|
**License**: MIT License
|
|
|
|
Feel free to:
|
|
- ✅ Use for personal projects
|
|
- ✅ Use for commercial events
|
|
- ✅ Modify and customize
|
|
- ✅ Redistribute with attribution
|
|
|
|
## Credits
|
|
|
|
**Created by**: grabowski
|
|
**Purpose**: Capture guest messages at weddings and events in a unique, nostalgic way
|
|
**Inspired by**: Vintage telephone systems and the desire to preserve wedding memories
|
|
|
|
### Technologies Used
|
|
|
|
- Python 3.8+
|
|
- Flask web framework
|
|
- PyAudio for audio handling
|
|
- RPi.GPIO for hardware control
|
|
- UV package manager
|
|
- HiFiBerry DAC+ADC Pro
|
|
- Systemd for service management
|
|
|
|
## Support & Community
|
|
|
|
- **Issues**: [GitHub Issues](https://git.b4l.co.th/grabowski/wedding-phone/issues)
|
|
- **Documentation**: This README and [CHANGELOG.md](CHANGELOG.md)
|
|
- **Repository**: https://git.b4l.co.th/grabowski/wedding-phone
|
|
|
|
## Acknowledgments
|
|
|
|
Thanks to everyone who has contributed ideas, bug reports, and improvements to make this project better!
|
|
|
|
---
|
|
|
|
**Made with ❤️ for preserving wedding memories** 🎉📞💍
|