fix this mess of libraries

This commit is contained in:
2026-07-05 17:49:51 +02:00
parent b09834b801
commit 8e4709f456
24 changed files with 62 additions and 82 deletions
+79
View File
@@ -0,0 +1,79 @@
#include "audio.h"
int init_PulseInputDevice(PulseInputDevice* dev, const int sample_rate, const int channels, const char* app_name, const char *stream_name, const char* device, pa_buffer_attr* buffer_attr, enum pa_sample_format format) {
#ifdef PULSE_DEBUG
debug_printf("Initializing PulseInputDevice format with app_name: %s, stream_name: %s, device: %s, sample_rate: %d, channels: %d, format: %d\n", app_name, stream_name, device, sample_rate, channels, format);
#endif
if (dev->initialized) return PA_ERR_BADSTATE;
pa_sample_spec sample_spec = {.format = format, .channels = channels, .rate = sample_rate};
if (!pa_sample_spec_valid(&sample_spec)) return PA_ERR_INVALID;
pa_buffer_attr new_buffer_attr = *buffer_attr;
dev->sample_spec = sample_spec;
dev->buffer_attr = new_buffer_attr;
dev->app_name = strdup(app_name);
dev->stream_name = strdup(stream_name);
dev->device = strdup(device);
dev->input = 1;
int error;
dev->dev = pa_simple_new(NULL, app_name, PA_STREAM_RECORD, device, stream_name, &sample_spec, NULL, &new_buffer_attr, &error);
if (!dev->dev) return error;
dev->initialized = 1;
return 0;
}
int read_PulseInputDevice(PulseInputDevice* dev, void* buffer, size_t size) {
if (!dev->initialized) return PA_ERR_BADSTATE;
int error = 0;
pa_simple_read(dev->dev, buffer, size, &error);
return error;
}
void free_PulseDevice(PulseDevice* dev) {
#ifdef PULSE_DEBUG
debug_printf("Freeing PulseDevice with app_name: %s, stream_name: %s, device: %s, input: %d\n", dev->app_name, dev->stream_name, dev->device, dev->input);
#endif
if (!dev->input) pa_simple_drain(dev->dev, NULL);
if (dev->dev && dev->initialized) pa_simple_free(dev->dev);
free(dev->app_name);
free(dev->stream_name);
free(dev->device);
dev->initialized = 0;
}
int init_PulseOutputDevice(PulseOutputDevice* dev, const int sample_rate, const int channels, const char* app_name, const char *stream_name, const char* device, pa_buffer_attr* buffer_attr, enum pa_sample_format format) {
#ifdef PULSE_DEBUG
debug_printf("Initializing PulseOutputDevice format with app_name: %s, stream_name: %s, device: %s, sample_rate: %d, channels: %d, format: %d\n", app_name, stream_name, device, sample_rate, channels, format);
#endif
if (dev->initialized) return PA_ERR_BADSTATE;
pa_sample_spec sample_spec = {.format = format, .channels = channels, .rate = sample_rate};
pa_buffer_attr new_buffer_attr = *buffer_attr;
dev->sample_spec = sample_spec;
dev->buffer_attr = new_buffer_attr;
dev->app_name = strdup(app_name);
dev->stream_name = strdup(stream_name);
dev->device = strdup(device);
dev->input = 0;
int error;
dev->dev = pa_simple_new(NULL, app_name, PA_STREAM_PLAYBACK, device, stream_name, &sample_spec, NULL, &new_buffer_attr, &error);
if (!dev->dev) return error;
dev->initialized = 1;
return 0;
}
int write_PulseOutputDevice(PulseOutputDevice* dev, void* buffer, size_t size) {
if (!dev->initialized) return PA_ERR_BADSTATE;
int error = 0;
if(pa_simple_write(dev->dev, buffer, size, &error) == 0) return 0;
return error;
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include <pulse/simple.h>
#include <pulse/error.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#ifdef DEBUG
#define PULSE_DEBUG
#endif
#ifdef PULSE_DEBUG
#include "debug.h"
#endif
typedef struct
{
pa_simple* dev;
pa_sample_spec sample_spec;
pa_buffer_attr buffer_attr;
char* app_name;
char* stream_name;
char* device;
bool initialized;
bool input;
} PulseDevice;
typedef PulseDevice PulseInputDevice;
int init_PulseInputDevice(PulseInputDevice* dev, const int sample_rate, const int channels, const char* app_name, const char *stream_name, const char* device, pa_buffer_attr* buffer_attr, enum pa_sample_format format);
int read_PulseInputDevice(PulseInputDevice *dev, void *buffer, size_t size);
void free_PulseDevice(PulseDevice *dev);
typedef PulseDevice PulseOutputDevice;
int init_PulseOutputDevice(PulseOutputDevice* dev, const int sample_rate, const int channels, const char* app_name, const char *stream_name, const char* device, pa_buffer_attr* buffer_attr, enum pa_sample_format format);
int write_PulseOutputDevice(PulseOutputDevice *dev, void *buffer, size_t size);
-7
View File
@@ -1,7 +0,0 @@
#pragma once
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_2PI
#define M_2PI (M_PI * 2.0)
#endif
-4
View File
@@ -1,4 +0,0 @@
#pragma once
#include <stdio.h>
#define debug_printf(fmt, ...) \
printf("[%s:%d in %s] " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
+97
View File
@@ -0,0 +1,97 @@
#include "ipc.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <sys/un.h>
static int make_server_socket(const char *path)
{
int fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) { perror("ipc: socket"); return -1; }
unlink(path);
struct sockaddr_un addr = { .sun_family = AF_UNIX };
strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("ipc: bind"); close(fd); return -1;
}
if (listen(fd, IPC_BACKLOG) < 0) {
perror("ipc: listen"); close(fd); return -1;
}
return fd;
}
static void *listener_thread(void *arg) {
ipc_ctx_t *ctx = (ipc_ctx_t *)arg;
while (ctx->running) {
struct sockaddr_un peer;
socklen_t peer_len = sizeof(peer);
int client_fd = accept(ctx->server_fd,
(struct sockaddr *)&peer, &peer_len);
if (client_fd < 0) {
if (errno == EINVAL || errno == EBADF) break; /* shutting down */
if (errno == EINTR) continue;
perror("ipc: accept");
continue;
}
printf("[ipc] new client fd=%d\n", client_fd);
ipc_client_arg_t *carg = malloc(sizeof(ipc_client_arg_t));
if (!carg) { close(client_fd); continue; }
carg->client_fd = client_fd;
carg->user_data = ctx->user_data;
pthread_t tid;
if (pthread_create(&tid, NULL,
(void *(*)(void *))ctx->handler, carg) != 0) {
perror("ipc: pthread_create");
free(carg);
close(client_fd);
continue;
}
pthread_detach(tid);
}
printf("[ipc] listener exiting\n");
return NULL;
}
int create_ipc(ipc_ctx_t *ctx, ipc_client_fn handler,
const char *socket_path, void *user_data)
{
ctx->handler = handler;
ctx->user_data = user_data;
ctx->running = 1;
ctx->server_fd = make_server_socket(socket_path);
ctx->socket_path = strdup(socket_path);
if (ctx->server_fd < 0) return -1;
pthread_t tid;
if (pthread_create(&tid, NULL, listener_thread, ctx) != 0) {
perror("ipc: pthread_create");
close(ctx->server_fd);
unlink(socket_path);
return -1;
}
ctx->_tid = tid;
printf("[ipc] listening on %s\n", socket_path);
return 0;
}
void destroy_ipc(ipc_ctx_t *ctx) {
ctx->running = 0;
shutdown(ctx->server_fd, SHUT_RDWR); /* unblock accept() */
close(ctx->server_fd);
unlink(ctx->socket_path);
pthread_join(ctx->_tid, NULL);
printf("[ipc] shut down\n");
}
+29
View File
@@ -0,0 +1,29 @@
#pragma once
#include <stdint.h>
#include <pthread.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#define IPC_BACKLOG 1
typedef struct {
int client_fd;
void *user_data;
} ipc_client_arg_t;
typedef void *(*ipc_client_fn)(ipc_client_arg_t *arg);
typedef struct {
int server_fd;
volatile int running;
ipc_client_fn handler;
void *user_data;
pthread_t _tid; /* internal — do not touch */
char *socket_path;
} ipc_ctx_t;
int create_ipc(ipc_ctx_t *ctx, ipc_client_fn handler,
const char *socket_path, void *user_data);
void destroy_ipc(ipc_ctx_t *ctx);
+36
View File
@@ -0,0 +1,36 @@
#include "oscillator.h"
void init_oscillator(Oscillator *osc, float frequency, float sample_rate) {
osc->phase = 0.0f;
osc->phase_increment = (M_2PI * frequency) / sample_rate;
osc->sample_rate = sample_rate;
}
inline void change_oscillator_frequency(Oscillator *osc, float frequency) {
osc->phase_increment = (M_2PI * frequency) / osc->sample_rate;
}
float get_oscillator_sin_sample(Oscillator *osc) {
float sample = sinf(osc->phase);
advance_oscillator(osc);
return sample;
}
float get_oscillator_cos_sample(Oscillator *osc) {
float sample = cosf(osc->phase);
advance_oscillator(osc);
return sample;
}
float get_oscillator_sin_multiplier_ni(Oscillator *osc, float multiplier) {
return sinf(osc->phase * multiplier);
}
float get_oscillator_cos_multiplier_ni(Oscillator *osc, float multiplier) {
return cosf(osc->phase * multiplier);
}
inline void advance_oscillator(Oscillator *osc) {
osc->phase += osc->phase_increment;
if (osc->phase >= M_2PI) osc->phase -= M_2PI;
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "constants.h"
#include <math.h>
typedef struct {
float phase;
float phase_increment;
float sample_rate;
} Oscillator;
void init_oscillator(Oscillator *osc, float frequency, float sample_rate);
void change_oscillator_frequency(Oscillator *osc, float frequency);
float get_oscillator_sin_sample(Oscillator *osc);
float get_oscillator_cos_sample(Oscillator *osc);
float get_oscillator_sin_multiplier_ni(Oscillator *osc, float multiplier);
float get_oscillator_cos_multiplier_ni(Oscillator *osc, float multiplier);
void advance_oscillator(Oscillator *osc);
-102
View File
@@ -1,102 +0,0 @@
#include <pulse/simple.h>
#define VBAN_SR_MAXNUMBER 21
static long VBAN_SRList[VBAN_SR_MAXNUMBER] = {
6000, 12000, 24000, 48000, 96000, 192000, 384000,
8000, 16000, 32000, 64000, 128000, 256000, 512000,
11025, 22050, 44100, 88200, 176400, 352800, 705600
};
#define VBAN_BIT_MAXNUMBER 5 // 7 in the standard but pa does these 5
static enum pa_sample_format VBAN_BITList[VBAN_BIT_MAXNUMBER] = {
PA_SAMPLE_U8,
PA_SAMPLE_S16NE,
PA_SAMPLE_S24NE,
PA_SAMPLE_S32NE,
PA_SAMPLE_FLOAT32NE,
};
static char VBAN_TextBITList[VBAN_BIT_MAXNUMBER][4] = {
"U08",
"S16",
"S24",
"S32",
"F32",
};
#define VBAN_PROTOCOL_AUDIO 0x00
#define VBAN_PROTOCOL_SERIAL 0x20
#define VBAN_PROTOCOL_TXT 0x40
#define VBAN_PROTOCOL_SERVICE 0x60
#define VBAN_SERVICE_IDENTIFICATION 0
#define VBAN_SERVICE_CHATUTF8 1
#define VBAN_SERVICE_RTPACKETREGISTER 32
#define VBAN_SERVICE_RTPACKET 33
#define VBANPING_TYPE_RECEPTOR 0x00000001 // Simple receptor
#define VBANPING_TYPE_TRANSMITTER 0x00000002 // Simple Transmitter
#define VBANPING_TYPE_RECEPTORSPOT 0x00000004 // SPOT receptor (able to receive several streams)
#define VBANPING_TYPE_TRANSMITTERSPOT 0x00000008 // SPOT transmitter (able to send several streams)
#define VBANPING_TYPE_VIRTUALDEVICE 0x00000010 // Virtual Device
#define VBANPING_TYPE_VIRTUALMIXER 0x00000020 // Virtual Mixer
#define VBANPING_TYPE_MATRIX 0x00000040 // MATRIX
#define VBANPING_TYPE_DAW 0x00000080 // Workstation
#define VBANPING_TYPE_SERVER 0x01000000 // VBAN SERVER
#define VBANPING_FEATURE_AUDIO 0x00000001
#define VBANPING_FEATURE_AOIP 0x00000002
#define VBANPING_FEATURE_VOIP 0x00000004
#define VBANPING_FEATURE_SERIAL 0x00000100
#define VBANPING_FEATURE_MIDI 0x00000300
#define VBANPING_FEATURE_FRAME 0x00001000
#define VBANPING_FEATURE_TXT 0x00010000
#pragma pack(1)
typedef struct {
char vban[4];
uint8_t protocol_sample_rate_idx; // format_SR
uint8_t samples_per_frame; // format_nbs
uint8_t sample_channels; // format_nbc
uint8_t format_type; // format_bit
char streamname[16];
uint32_t frame_num; // nuFrame
} VBANHeader;
typedef union {
VBANHeader packet_data;
char raw_data[sizeof(VBANHeader)];
} VBANHeaderUnion;
typedef struct {
uint32_t bitType;
uint32_t bitfeature;
uint32_t bitfeatureEx;
uint32_t PreferredRate;
uint32_t MinRate;
uint32_t MaxRate;
uint32_t colorRGB;
uint8_t nVersion[4];
char GPS_Position[8];
char USER_Position[8];
char LangCode_ascii[8];
char reserved_ascii[8];
char reservedEx[64];
char DistantIP_ascii[32];
uint16_t DistantPort;
uint16_t DistantReserved;
char DeviceName_ascii[64];
char ManufacturerName_ascii[64];
char ApplicationName_ascii[64];
char HostName_ascii[64];
char UserName_utf8[128];
char UserComment_utf8[128];
} VBANPing0Data;
typedef union {
VBANPing0Data data;
char raw_data[sizeof(VBANPing0Data)];
} VBANPing0DataUnion;
#pragma pack()