Milestone1
This commit is contained in:
parent
a1094ab7ea
commit
4addf989cc
17 changed files with 2876 additions and 0 deletions
272
VERIFICATION.md
Normal file
272
VERIFICATION.md
Normal 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**
|
||||
Loading…
Add table
Add a link
Reference in a new issue