mirror of
https://github.com/radio95-rnt/fm95.git
synced 2026-07-30 00:09:16 +02:00
fix this mess of libraries
This commit is contained in:
+79
@@ -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
@@ -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);
|
||||
@@ -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
|
||||
@@ -1,4 +0,0 @@
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#define debug_printf(fmt, ...) \
|
||||
printf("[%s:%d in %s] " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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()
|
||||
Reference in New Issue
Block a user