Audio capture and streaming app for webOS 5/6
Captures the TV's audio and sends it out over several transports. The
primary one is HyperHDR: RTP/L16 to a host-side loopback device, since
HyperHDR has no network audio input of its own. A second route renders
the spectrum on the TV and sends FlatBuffers images to port 19400
instead, for setups where touching the host's sound config is not an
option.
native/ the service: capture backends (PulseAudio, ALSA, exec,
test tone, all dlopen-based), DSP, and one file per sink
frontend/ D-pad driven UI at a fixed 1920x1080
servicefiles/ native service manifest plus the boot script
host/ RTP receiver and the loopback installer for the HyperHDR
machine
tools/ build/package, asset generation, Homebrew Channel
manifest, on-TV probe
test/ host-side suites: FlatBuffers and RTP verified against
real decoders, the engine end to end, the page in jsdom
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
// See glib.h in this directory: syntax-check scaffolding, not a real header.
|
||||
#pragma once
|
||||
|
||||
#include "glib.h"
|
||||
|
||||
guint g_unix_signal_add(gint signum, GSourceFunc handler, gpointer user_data);
|
||||
@@ -0,0 +1,32 @@
|
||||
// Minimal glib stand-in, used only to syntax-check service.c and main.c on a
|
||||
// development machine that has no webOS SDK installed. It declares exactly the
|
||||
// handful of symbols this project uses and nothing else; the real headers are
|
||||
// what the TV build compiles against.
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef int gboolean;
|
||||
typedef int gint;
|
||||
typedef unsigned int guint;
|
||||
typedef void* gpointer;
|
||||
|
||||
typedef struct _GMainLoop GMainLoop;
|
||||
typedef struct _GMainContext GMainContext;
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define G_SOURCE_REMOVE FALSE
|
||||
#define G_SOURCE_CONTINUE TRUE
|
||||
|
||||
typedef gboolean (*GSourceFunc)(gpointer user_data);
|
||||
|
||||
GMainLoop* g_main_loop_new(GMainContext* context, gboolean is_running);
|
||||
void g_main_loop_run(GMainLoop* loop);
|
||||
void g_main_loop_quit(GMainLoop* loop);
|
||||
void g_main_loop_unref(GMainLoop* loop);
|
||||
|
||||
guint g_idle_add(GSourceFunc function, gpointer data);
|
||||
|
||||
gboolean g_atomic_int_compare_and_exchange(gint* atomic, gint oldval, gint newval);
|
||||
void g_atomic_int_set(gint* atomic, gint newval);
|
||||
@@ -0,0 +1,63 @@
|
||||
// Minimal luna-service2 stand-in for host-side syntax checks. Mirrors the
|
||||
// signatures this project calls, so a typo or a wrong argument count is caught
|
||||
// without a webOS SDK. See ../glib.h.
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct LSHandle LSHandle;
|
||||
typedef struct LSMessage LSMessage;
|
||||
|
||||
typedef struct {
|
||||
int error_code;
|
||||
char* message;
|
||||
const char* file;
|
||||
int line;
|
||||
const char* func;
|
||||
void* padding;
|
||||
unsigned long magic;
|
||||
} LSError;
|
||||
|
||||
typedef bool (*LSMethodFunction)(LSHandle* sh, LSMessage* msg, void* category_context);
|
||||
|
||||
typedef enum {
|
||||
LUNA_METHOD_FLAGS_NONE = 0,
|
||||
} LSMethodFlags;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
LSMethodFunction function;
|
||||
LSMethodFlags flags;
|
||||
} LSMethod;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
void* function;
|
||||
unsigned int flags;
|
||||
} LSSignal;
|
||||
|
||||
typedef struct {
|
||||
const char* name;
|
||||
void* function;
|
||||
unsigned int flags;
|
||||
} LSProperty;
|
||||
|
||||
void LSErrorInit(LSError* error);
|
||||
void LSErrorFree(LSError* error);
|
||||
|
||||
bool LSRegister(const char* name, LSHandle** handle, LSError* error);
|
||||
bool LSUnregister(LSHandle* handle, LSError* error);
|
||||
|
||||
bool LSRegisterCategory(LSHandle* handle, const char* category, LSMethod* methods,
|
||||
LSSignal* signals, LSProperty* properties, LSError* error);
|
||||
bool LSCategorySetData(LSHandle* handle, const char* category, void* user_data, LSError* error);
|
||||
|
||||
bool LSGmainAttach(LSHandle* handle, GMainLoop* loop, LSError* error);
|
||||
|
||||
const char* LSMessageGetPayload(LSMessage* message);
|
||||
bool LSMessageIsSubscription(LSMessage* message);
|
||||
bool LSMessageReply(LSHandle* sh, LSMessage* message, const char* reply, LSError* error);
|
||||
|
||||
bool LSSubscriptionAdd(LSHandle* sh, const char* key, LSMessage* message, LSError* error);
|
||||
bool LSSubscriptionReply(LSHandle* sh, const char* key, const char* payload, LSError* error);
|
||||
Reference in New Issue
Block a user