272 lines
7.7 KiB
Markdown
272 lines
7.7 KiB
Markdown
# 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**
|