|
| 1 | +# ============================================================================= |
| 2 | +# Linux Voice Assistant |
| 3 | +# ============================================================================= |
| 4 | +# A complete voice AI pipeline for Raspberry Pi 5 (and other Linux devices) |
| 5 | +# using runanywhere-commons as the ML backend. |
| 6 | +# |
| 7 | +# Pipeline: VAD -> STT -> LLM -> TTS |
| 8 | +# |
| 9 | +# Build instructions: |
| 10 | +# 1. Build runanywhere-commons for Linux first: |
| 11 | +# cd sdk/runanywhere-commons |
| 12 | +# ./scripts/linux/download-sherpa-onnx.sh |
| 13 | +# ./scripts/build-linux.sh --shared |
| 14 | +# |
| 15 | +# 2. Build this application: |
| 16 | +# cd Playground/linux-voice-assistant |
| 17 | +# cmake -B build |
| 18 | +# cmake --build build |
| 19 | +# |
| 20 | +# 3. Download models: |
| 21 | +# ./scripts/download-models.sh |
| 22 | +# |
| 23 | +# 4. Run: |
| 24 | +# ./build/voice-assistant |
| 25 | +# ============================================================================= |
| 26 | + |
| 27 | +cmake_minimum_required(VERSION 3.16) |
| 28 | +project(linux-voice-assistant |
| 29 | + VERSION 1.0.0 |
| 30 | + LANGUAGES CXX |
| 31 | + DESCRIPTION "Linux Voice Assistant using RunAnywhere Commons" |
| 32 | +) |
| 33 | + |
| 34 | +set(CMAKE_CXX_STANDARD 17) |
| 35 | +set(CMAKE_CXX_STANDARD_REQUIRED ON) |
| 36 | + |
| 37 | +# ============================================================================= |
| 38 | +# Configuration |
| 39 | +# ============================================================================= |
| 40 | + |
| 41 | +# Path to runanywhere-commons |
| 42 | +set(RAC_COMMONS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../sdk/runanywhere-commons") |
| 43 | +set(RAC_COMMONS_DIST "${RAC_COMMONS_DIR}/dist/linux/${CMAKE_SYSTEM_PROCESSOR}") |
| 44 | + |
| 45 | +# Check if runanywhere-commons is built |
| 46 | +if(NOT EXISTS "${RAC_COMMONS_DIST}/librac_commons.so") |
| 47 | + message(WARNING "runanywhere-commons not built. Build it first:") |
| 48 | + message(WARNING " cd ${RAC_COMMONS_DIR}") |
| 49 | + message(WARNING " ./scripts/linux/download-sherpa-onnx.sh") |
| 50 | + message(WARNING " ./scripts/build-linux.sh --shared") |
| 51 | +endif() |
| 52 | + |
| 53 | +# ============================================================================= |
| 54 | +# Find Dependencies |
| 55 | +# ============================================================================= |
| 56 | + |
| 57 | +# ALSA for audio I/O |
| 58 | +find_package(ALSA REQUIRED) |
| 59 | +if(ALSA_FOUND) |
| 60 | + message(STATUS "Found ALSA: ${ALSA_INCLUDE_DIRS}") |
| 61 | +else() |
| 62 | + message(FATAL_ERROR "ALSA not found. Install with: apt install libasound2-dev") |
| 63 | +endif() |
| 64 | + |
| 65 | +# PulseAudio (optional, for better audio routing) |
| 66 | +find_package(PkgConfig) |
| 67 | +if(PKG_CONFIG_FOUND) |
| 68 | + pkg_check_modules(PULSE libpulse libpulse-simple) |
| 69 | + if(PULSE_FOUND) |
| 70 | + message(STATUS "Found PulseAudio: ${PULSE_INCLUDE_DIRS}") |
| 71 | + endif() |
| 72 | +endif() |
| 73 | + |
| 74 | +# Threads |
| 75 | +find_package(Threads REQUIRED) |
| 76 | + |
| 77 | +# ============================================================================= |
| 78 | +# Source Files |
| 79 | +# ============================================================================= |
| 80 | + |
| 81 | +set(SOURCES |
| 82 | + src/main.cpp |
| 83 | + src/pipeline/voice_pipeline.cpp |
| 84 | + src/audio/audio_capture.cpp |
| 85 | + src/audio/audio_playback.cpp |
| 86 | +) |
| 87 | + |
| 88 | +set(HEADERS |
| 89 | + src/config/model_config.h |
| 90 | + src/pipeline/voice_pipeline.h |
| 91 | + src/audio/audio_capture.h |
| 92 | + src/audio/audio_playback.h |
| 93 | +) |
| 94 | + |
| 95 | +# ============================================================================= |
| 96 | +# Executable |
| 97 | +# ============================================================================= |
| 98 | + |
| 99 | +add_executable(voice-assistant ${SOURCES} ${HEADERS}) |
| 100 | + |
| 101 | +# Test pipeline binary (feeds WAV file through the full pipeline) |
| 102 | +add_executable(test-pipeline tests/test_pipeline.cpp) |
| 103 | + |
| 104 | +# ============================================================================= |
| 105 | +# Include Directories |
| 106 | +# ============================================================================= |
| 107 | + |
| 108 | +target_include_directories(voice-assistant PRIVATE |
| 109 | + ${CMAKE_CURRENT_SOURCE_DIR}/src |
| 110 | + ${RAC_COMMONS_DIR}/include |
| 111 | + ${RAC_COMMONS_DIST}/include |
| 112 | + ${ALSA_INCLUDE_DIRS} |
| 113 | +) |
| 114 | + |
| 115 | +if(PULSE_FOUND) |
| 116 | + target_include_directories(voice-assistant PRIVATE ${PULSE_INCLUDE_DIRS}) |
| 117 | + target_compile_definitions(voice-assistant PRIVATE USE_PULSEAUDIO=1) |
| 118 | +endif() |
| 119 | + |
| 120 | +# ============================================================================= |
| 121 | +# Link Libraries |
| 122 | +# ============================================================================= |
| 123 | + |
| 124 | +# Link runanywhere-commons libraries |
| 125 | +target_link_directories(voice-assistant PRIVATE |
| 126 | + ${RAC_COMMONS_DIST} |
| 127 | + ${RAC_COMMONS_DIR}/third_party/sherpa-onnx-linux/lib |
| 128 | +) |
| 129 | + |
| 130 | +target_link_libraries(voice-assistant PRIVATE |
| 131 | + # RunAnywhere Commons |
| 132 | + rac_commons |
| 133 | + rac_backend_onnx |
| 134 | + rac_backend_llamacpp |
| 135 | + |
| 136 | + # Sherpa-ONNX (for STT/TTS/VAD) |
| 137 | + sherpa-onnx-c-api |
| 138 | + |
| 139 | + # ONNX Runtime |
| 140 | + onnxruntime |
| 141 | + |
| 142 | + # System libraries |
| 143 | + ${ALSA_LIBRARIES} |
| 144 | + Threads::Threads |
| 145 | + dl |
| 146 | +) |
| 147 | + |
| 148 | +if(PULSE_FOUND) |
| 149 | + target_link_libraries(voice-assistant PRIVATE ${PULSE_LIBRARIES}) |
| 150 | +endif() |
| 151 | + |
| 152 | +# ============================================================================= |
| 153 | +# RPATH Configuration |
| 154 | +# ============================================================================= |
| 155 | + |
| 156 | +# Set RPATH so the executable can find libraries at runtime |
| 157 | +set_target_properties(voice-assistant PROPERTIES |
| 158 | + BUILD_RPATH "${RAC_COMMONS_DIST};${RAC_COMMONS_DIR}/third_party/sherpa-onnx-linux/lib" |
| 159 | + INSTALL_RPATH "$ORIGIN/../lib;$ORIGIN/../../sdk/runanywhere-commons/dist/linux/${CMAKE_SYSTEM_PROCESSOR}" |
| 160 | +) |
| 161 | + |
| 162 | +# ============================================================================= |
| 163 | +# Compiler Options |
| 164 | +# ============================================================================= |
| 165 | + |
| 166 | +target_compile_options(voice-assistant PRIVATE |
| 167 | + -Wall |
| 168 | + -Wextra |
| 169 | + -Wpedantic |
| 170 | + -O2 |
| 171 | +) |
| 172 | + |
| 173 | +# ============================================================================= |
| 174 | +# Test Pipeline Configuration |
| 175 | +# ============================================================================= |
| 176 | + |
| 177 | +target_include_directories(test-pipeline PRIVATE |
| 178 | + ${CMAKE_CURRENT_SOURCE_DIR}/src |
| 179 | + ${RAC_COMMONS_DIR}/include |
| 180 | + ${RAC_COMMONS_DIST}/include |
| 181 | +) |
| 182 | + |
| 183 | +target_link_directories(test-pipeline PRIVATE |
| 184 | + ${RAC_COMMONS_DIST} |
| 185 | + ${RAC_COMMONS_DIR}/third_party/sherpa-onnx-linux/lib |
| 186 | +) |
| 187 | + |
| 188 | +target_link_libraries(test-pipeline PRIVATE |
| 189 | + rac_commons |
| 190 | + rac_backend_onnx |
| 191 | + rac_backend_llamacpp |
| 192 | + sherpa-onnx-c-api |
| 193 | + onnxruntime |
| 194 | + Threads::Threads |
| 195 | + dl |
| 196 | +) |
| 197 | + |
| 198 | +set_target_properties(test-pipeline PROPERTIES |
| 199 | + BUILD_RPATH "${RAC_COMMONS_DIST};${RAC_COMMONS_DIR}/third_party/sherpa-onnx-linux/lib" |
| 200 | +) |
| 201 | + |
| 202 | +target_compile_options(test-pipeline PRIVATE -Wall -O2) |
| 203 | + |
| 204 | +# ============================================================================= |
| 205 | +# Installation |
| 206 | +# ============================================================================= |
| 207 | + |
| 208 | +install(TARGETS voice-assistant |
| 209 | + RUNTIME DESTINATION bin |
| 210 | +) |
| 211 | + |
| 212 | +# Install run script |
| 213 | +install(FILES scripts/download-models.sh |
| 214 | + DESTINATION bin |
| 215 | + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE |
| 216 | + GROUP_READ GROUP_EXECUTE |
| 217 | + WORLD_READ WORLD_EXECUTE |
| 218 | +) |
| 219 | + |
| 220 | +# ============================================================================= |
| 221 | +# Summary |
| 222 | +# ============================================================================= |
| 223 | + |
| 224 | +message(STATUS "") |
| 225 | +message(STATUS "========================================") |
| 226 | +message(STATUS "Linux Voice Assistant Configuration") |
| 227 | +message(STATUS "========================================") |
| 228 | +message(STATUS "") |
| 229 | +message(STATUS "RunAnywhere Commons: ${RAC_COMMONS_DIR}") |
| 230 | +message(STATUS "RAC Distribution: ${RAC_COMMONS_DIST}") |
| 231 | +message(STATUS "") |
| 232 | +message(STATUS "Dependencies:") |
| 233 | +message(STATUS " ALSA: ${ALSA_LIBRARIES}") |
| 234 | +if(PULSE_FOUND) |
| 235 | + message(STATUS " PulseAudio: ${PULSE_LIBRARIES}") |
| 236 | +else() |
| 237 | + message(STATUS " PulseAudio: Not found (optional)") |
| 238 | +endif() |
| 239 | +message(STATUS "") |
| 240 | +message(STATUS "Build with:") |
| 241 | +message(STATUS " cmake -B build && cmake --build build") |
| 242 | +message(STATUS "") |
| 243 | +message(STATUS "Before running, download models:") |
| 244 | +message(STATUS " ./scripts/download-models.sh") |
| 245 | +message(STATUS "") |
| 246 | +message(STATUS "========================================") |
0 commit comments