Milestone1

This commit is contained in:
Joey Yakimowich-Payne 2026-01-27 15:24:29 -07:00
commit 4addf989cc
17 changed files with 2876 additions and 0 deletions

272
VERIFICATION.md Normal file
View file

@ -0,0 +1,272 @@
# Milestone 1 Verification Guide
## Current Status
**Code Complete** - All Milestone 1 code has been written
⚠️ **Build Blocked** - Development dependencies not installed on this system
**PipeWire Running** - Runtime PipeWire daemon verified (v1.4.10)
## What's Been Completed
### 1. Project Structure ✅
- CMakeLists.txt with Qt6 and PipeWire integration
- Source directory structure (`src/pipewire/`)
- Build configuration for static library + test executable
- .gitignore and README.md
### 2. Core PipeWire Integration ✅
**Files Created:**
- `pipewirecontroller.{h,cpp}` - 473 lines
- `nodeinfo.{h,cpp}` - Data structures
- `main_test.cpp` - CLI test harness (222 lines)
**Key Features Implemented:**
- ✅ `pw_thread_loop` initialization (non-blocking)
- ✅ Registry callbacks for node/port/link discovery
- ✅ Thread-safe node/port/link storage with QMutex
- ✅ QAtomicInteger for connection state
- ✅ Link creation via `pw_core_create_object`
- ✅ Link destruction via `pw_proxy_destroy`
- ✅ Qt signals: `nodeAdded`, `nodeRemoved`, `linkAdded`, `linkRemoved`, `errorOccurred`
- ✅ Error handling for PipeWire disconnection (EPIPE detection)
- ✅ Graph dump functionality for debugging
### 3. Test Application ✅
**`potato-test` CLI tool includes:**
- Automatic node discovery with 2-second wait
- Node listing with type/class categorization
- Automatic link creation between first available source/sink
- Link deletion after 2 seconds
- Final graph dump
- Clean shutdown sequence
## Installation Steps (When Ready)
### Fedora/RHEL/Rocky Linux
```bash
sudo dnf install cmake qt6-qtbase-devel pipewire-devel gcc-c++ pkg-config
```
### Ubuntu/Debian
```bash
sudo apt install cmake qt6-base-dev libpipewire-0.3-dev build-essential pkg-config
```
### Arch Linux
```bash
sudo pacman -S cmake qt6-base pipewire gcc pkg-config
```
## Build Instructions
```bash
cd /var/home/joey/Downloads/potato
mkdir build
cd build
cmake ..
make -j$(nproc)
```
Expected output:
```
-- The CXX compiler identification is GNU X.X.X
-- Found Qt6Core: ...
-- Found PkgConfig: /usr/bin/pkg-config
-- Found PIPEWIRE: ...
-- Found SPA: ...
-- Configuring done
-- Generating done
-- Build files written to: .../build
```
## Running Tests
### Test 1: Node Discovery
```bash
./build/potato-test
```
**Expected Output:**
```
=== Potato Audio Router - PipeWire Integration Test ===
Version: 1.0.0
Initializing PipeWire...
PipeWire initialized successfully
Waiting for nodes to be discovered...
=== Running PipeWire Tests ===
Test 1: List all nodes
Found X nodes:
[42] alsa_output.pci-0000_00_1f.3.analog-stereo
Type: Hardware | Class: Sink
Description: Built-in Audio Analog Stereo
Inputs: 2 | Outputs: 0
[43] alsa_input.pci-0000_00_1f.3.analog-stereo
Type: Hardware | Class: Source
Description: Built-in Audio Analog Stereo
Inputs: 0 | Outputs: 2
...
```
### Test 2: Link Creation
After listing nodes, the test should automatically:
```
Test 2: Create a link between two nodes
Creating link from alsa_input.pci-0000_00_1f.3.analog-stereo to alsa_output.pci-0000_00_1f.3.analog-stereo
[EVENT] Link added: 123
Link created successfully with ID: 123
```
### Test 3: Link Deletion
```
Test 3: Delete the link
[EVENT] Link removed: 123
Link deleted successfully
```
### Test 4: Graph Dump
```
=== Tests Complete ===
Final graph dump:
=== PipeWire Graph Dump ===
Nodes: X
Ports: Y
Links: Z
=== Nodes ===
Node 42: alsa_output.pci-0000_00_1f.3.analog-stereo
Description: Built-in Audio Analog Stereo
Stable ID: alsa_output.pci-0000_00_1f.3.analog-stereo
Input ports: 2
Output ports: 0
...
```
## Verification Checklist
Once dependencies are installed, verify:
### ✅ Compilation
- [ ] CMake configures without errors
- [ ] `make` completes successfully
- [ ] No compiler warnings with `-Wall -Wextra`
- [ ] `potato-test` executable is created
### ✅ Runtime - Node Discovery
- [ ] PipeWire connection establishes within 1 second
- [ ] At least 2 nodes discovered (typically 5-20 on a normal system)
- [ ] Hardware nodes have correct Type (Hardware)
- [ ] Sinks have input ports, Sources have output ports
- [ ] Node descriptions are human-readable
### ✅ Runtime - Link Creation
- [ ] Link creation returns non-zero ID
- [ ] `linkAdded` signal fires
- [ ] No "Failed to create link" errors
- [ ] Audio routing is active (can test with `pw-link` or audio playback)
### ✅ Runtime - Link Deletion
- [ ] `destroyLink` returns true
- [ ] `linkRemoved` signal fires
- [ ] Link no longer appears in graph dump
### ✅ Thread Safety
- [ ] No crashes during rapid node add/remove (plug/unplug USB audio)
- [ ] No Qt warnings about cross-thread signal emissions
- [ ] PipeWire thread runs independently (check with `top -H -p $(pgrep potato-test)`)
### ✅ Error Handling
- [ ] Graceful error if PipeWire not running: `systemctl --user stop pipewire && ./potato-test`
- [ ] Reconnection works if PipeWire restarts during operation
- [ ] Clean shutdown with Ctrl+C
## Known Limitations (Milestone 1)
This is a **CLI test application only**. Missing features (planned for later milestones):
- ❌ No GUI (Milestone 2)
- ❌ No visual node editor (Milestone 2)
- ❌ No real-time audio meters (Milestone 3)
- ❌ No volume control (Milestone 5)
- ❌ No preset management (Milestone 4)
- ❌ Link creation is programmatic only (GUI in Milestone 2)
## Troubleshooting
### CMake can't find Qt6
```bash
# Fedora: Ensure qt6 is in PATH
export CMAKE_PREFIX_PATH=/usr/lib64/cmake/Qt6
# Or specify manually
cmake -DCMAKE_PREFIX_PATH=/usr/lib64/cmake/Qt6 ..
```
### CMake can't find PipeWire
```bash
# Check pkg-config can find it
pkg-config --libs --cflags pipewire-0.3
# If not found, install pipewire-devel
sudo dnf install pipewire-devel
```
### Test fails: "Failed to connect to PipeWire daemon"
```bash
# Check PipeWire is running
systemctl --user status pipewire
pw-cli info all
# Start if needed
systemctl --user start pipewire
```
### Test reports: "Could not find suitable source and sink nodes"
This means PipeWire has no audio devices. Check:
```bash
# List available nodes
pw-cli ls Node
# You should see at least:
# - alsa_output.* (speakers/headphones)
# - alsa_input.* (microphone)
```
If no devices appear, PipeWire isn't configured properly. Try:
```bash
systemctl --user restart pipewire pipewire-pulse wireplumber
```
## Code Quality Notes
### Architecture Decisions
1. **pw_thread_loop**: Chosen over pw_main_loop for Qt compatibility (separate threads)
2. **QMutex**: Used for node/port/link maps (acceptable for non-real-time operations)
3. **QAtomicInteger**: Used for connection state (lock-free, real-time safe)
4. **Qt Signals**: Cross-thread communication from PipeWire callbacks to test app
5. **Registry callbacks**: Standard PipeWire pattern for graph discovery
### Thread Safety Analysis
- **PipeWire Thread**: Runs in `pw_thread_loop`, handles callbacks
- **Qt Thread**: Runs test application, receives signals
- **Critical Sections**: All PipeWire API calls wrapped in `lock()/unlock()`
- **Data Races**: Prevented by QMutex on all QMap access
### Potential Improvements (Future)
- Add `pw_stream` for actual audio processing (Milestone 3)
- Implement lock-free ring buffers for meter data (Milestone 3)
- Cache node metadata to reduce mutex contention
- Add retry logic for failed link creation
- Implement stable ID matching for device hotplug (Milestone 4)
## Acceptance Criteria
**✅ Milestone 1 is complete when:**
1. Code compiles without errors or warnings
2. `potato-test` lists at least 2 PipeWire nodes
3. Link can be created between source and sink programmatically
4. Link can be destroyed
5. Graph dump shows accurate state
**Status: CODE COMPLETE, AWAITING DEPENDENCY INSTALLATION FOR BUILD VERIFICATION**