Confirmed the brightness command applies globally, not per-LED
(serverinfo showed exactly one adjustment object, "id": "default",
covering the whole string), so no LED-count configuration is needed
for this at all -- that question resolved itself once the mechanism
was actually inspected instead of assumed.
For "only react while Spotify is running": only one app can be in the
foreground on webOS at a time, so a "capture the current app" button
in this app's own UI can never work -- pressing it means this app is
foreground, not Spotify. The only workable UI is picking a target from
every *installed* app by name, regardless of what's currently running.
That needed a new native capability this service never had: calling
OUT to another Luna service, not just being called. Two additions:
foreground_app.c subscribes once, at startup, to
com.webos.applicationManager/getForegroundAppInfo
and keeps a thread-safe cache the audio thread can
read without a blocking Luna call
service.c new listApps method, bridging to
com.webos.applicationManager/listApps so the
frontend never has to call another service
directly -- same rule as everywhere else here
Until the subscription has delivered at least one reply, a restricted
sink treats the target app as inactive, not active -- reacting to
audio when the user explicitly restricted it to one app would be the
wrong failure mode. Verified end to end on the host: engine_smoke.c
opens the sink with a restriction set, confirms it reports itself
correctly inactive against the stub Luna bus (which always "fails" to
call out, exactly like a real host with no bus).
Needed real, linkable stub bodies for LSCall/LSCallOneReply/
LSCallCancel/LSMessageGetPayload/LSErrorInit/LSErrorFree
(test/stubs/luna-service2/lunaservice_stub.c) since foreground_app.c
is the first source file here that's actually linked into a host test
binary rather than only syntax-checked -- service.c/main.c's existing
stub declarations were never called, only compiled against. Confirmed
those really are the correct symbol names by cross-compiling clean
against the real webOS SDK's actual libluna-service2, not just the
stub.
Bumped to 1.0.5.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
113 lines
3.1 KiB
CMake
113 lines
3.1 KiB
CMake
cmake_minimum_required(VERSION 3.5)
|
|
project(lgtv-audio-cap C)
|
|
|
|
# Built with the openlgtv arm-webos-linux-gnueabi buildroot SDK:
|
|
#
|
|
# source /path/to/arm-webos-linux-gnueabi_sdk-buildroot/environment-setup
|
|
# cmake -B build -DCMAKE_BUILD_TYPE=Release native
|
|
# cmake --build build
|
|
#
|
|
# The SDK's environment-setup exports CC/SYSROOT and puts its pkg-config in
|
|
# front, so luna-service2 and glib resolve to the TV's versions rather than the
|
|
# host's.
|
|
|
|
set(CMAKE_C_STANDARD 11)
|
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
|
|
if(NOT CMAKE_BUILD_TYPE)
|
|
set(CMAKE_BUILD_TYPE Release)
|
|
endif()
|
|
|
|
find_package(PkgConfig REQUIRED)
|
|
pkg_check_modules(LUNASERVICE REQUIRED luna-service2)
|
|
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
|
pkg_check_modules(GTHREAD REQUIRED gthread-2.0)
|
|
# PmLogLib is how webOS services normally reach the system log. It is optional
|
|
# here: the logger writes to stderr, which the service launcher captures.
|
|
pkg_check_modules(PMLOG PmLogLib)
|
|
|
|
add_executable(audiocap-service
|
|
src/main.c
|
|
src/service.c
|
|
src/engine.c
|
|
src/foreground_app.c
|
|
src/config.c
|
|
src/dsp.c
|
|
src/common/log.c
|
|
src/common/json.c
|
|
src/common/ringbuf.c
|
|
src/capture/capture.c
|
|
src/capture/cap_pulse.c
|
|
src/capture/cap_alsa.c
|
|
src/capture/cap_exec.c
|
|
src/capture/cap_tone.c
|
|
src/net/flatbuf.c
|
|
src/net/hyperion.c
|
|
src/net/streamserv.c
|
|
src/sinks/sink.c
|
|
src/sinks/sink_hyperhdr.c
|
|
src/sinks/sink_hyperhdr_viz.c
|
|
src/sinks/sink_hyperhdr_adjust.c
|
|
src/sinks/sink_udp.c
|
|
src/sinks/sink_tcp.c
|
|
src/sinks/sink_http.c
|
|
)
|
|
|
|
target_include_directories(audiocap-service PRIVATE
|
|
src
|
|
${LUNASERVICE_INCLUDE_DIRS}
|
|
${GLIB_INCLUDE_DIRS}
|
|
${GTHREAD_INCLUDE_DIRS}
|
|
${PMLOG_INCLUDE_DIRS}
|
|
)
|
|
|
|
target_compile_options(audiocap-service PRIVATE
|
|
-Wall -Wextra -Wno-unused-parameter
|
|
${LUNASERVICE_CFLAGS_OTHER}
|
|
${GLIB_CFLAGS_OTHER}
|
|
)
|
|
|
|
target_compile_definitions(audiocap-service PRIVATE
|
|
_GNU_SOURCE
|
|
# Lets LSRegisterPubPriv resolve on firmware older than 3.5 without making
|
|
# the symbol mandatory on newer builds.
|
|
SECURITY_COMPATIBILITY
|
|
)
|
|
|
|
# The audio backends are dlopen'd at runtime, so libpulse and libasound are
|
|
# deliberately absent from this list: the service has to start on a TV that has
|
|
# neither, report that in the diagnostics, and let the user pick another path.
|
|
target_link_libraries(audiocap-service PRIVATE
|
|
${LUNASERVICE_LIBRARIES}
|
|
${GLIB_LIBRARIES}
|
|
${GTHREAD_LIBRARIES}
|
|
${PMLOG_LIBRARIES}
|
|
pthread
|
|
dl
|
|
m
|
|
)
|
|
|
|
target_link_directories(audiocap-service PRIVATE
|
|
${LUNASERVICE_LIBRARY_DIRS}
|
|
${GLIB_LIBRARY_DIRS}
|
|
${GTHREAD_LIBRARY_DIRS}
|
|
${PMLOG_LIBRARY_DIRS}
|
|
)
|
|
|
|
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
|
|
# webOS 5/6 TVs are Cortex-A9 (and A53 on later chassis, which runs A9 code
|
|
# fine). softfp matches the SDK's ABI.
|
|
target_compile_options(audiocap-service PRIVATE
|
|
-mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=neon -ffast-math
|
|
)
|
|
endif()
|
|
|
|
# Homebrew services are unpacked to an arbitrary directory, so anything we ship
|
|
# alongside the binary has to be found relative to it.
|
|
set_target_properties(audiocap-service PROPERTIES
|
|
BUILD_RPATH "$ORIGIN"
|
|
INSTALL_RPATH "$ORIGIN"
|
|
)
|
|
|
|
install(TARGETS audiocap-service RUNTIME DESTINATION .)
|