#ifndef _VIRTUAL_INT_H_
#define _VIRTUAL_INT_H_
#include <signal.h>
#include <pthread.h>
#include <cuse.h>
#include <samplerate.h>
extern pthread_mutex_t atomic_mtx;
extern pthread_cond_t atomic_cv;
#define atomic_lock() pthread_mutex_lock(&atomic_mtx)
#define atomic_unlock() pthread_mutex_unlock(&atomic_mtx)
#define atomic_wait() pthread_cond_wait(&atomic_cv, &atomic_mtx)
#define atomic_wakeup() do { \
pthread_cond_broadcast(&atomic_cv); \
cuse_poll_wakeup(); \
} while (0)
#define AFMT_32BIT \
(AFMT_S32_LE | AFMT_S32_BE | AFMT_U32_LE | AFMT_U32_BE | \
AFMT_F32_LE | AFMT_F32_BE)
#define AFMT_24BIT \
(AFMT_S24_LE | AFMT_S24_BE | AFMT_U24_LE | AFMT_U24_BE)
#define AFMT_16BIT \
(AFMT_S16_LE | AFMT_S16_BE | AFMT_U16_LE | AFMT_U16_BE)
#define AFMT_8BIT \
(AFMT_U8 | AFMT_S8)
#define VMAX_CHAN 64
#define VMAX_STRING 27
#define VTYPE_OSS_DAT 0
#define VTYPE_WAV_HDR 1
#define VTYPE_WAV_DAT 2
#define VPREFERRED_SNE_AFMT \
(AFMT_S8 | AFMT_S16_NE | AFMT_S24_NE | AFMT_S32_NE)
#define VPREFERRED_UNE_AFMT \
(AFMT_U8 | AFMT_U16_NE | AFMT_U24_NE | AFMT_U32_NE)
#define VPREFERRED_SLE_AFMT \
(AFMT_S8 | AFMT_S16_LE | AFMT_S24_LE | AFMT_S32_LE)
#define VPREFERRED_SBE_AFMT \
(AFMT_S8 | AFMT_S16_BE | AFMT_S24_BE | AFMT_S32_BE)
#define VPREFERRED_ULE_AFMT \
(AFMT_U8 | AFMT_U16_LE | AFMT_U24_LE | AFMT_U32_LE)
#define VPREFERRED_UBE_AFMT \
(AFMT_U8 | AFMT_U16_BE | AFMT_U24_BE | AFMT_U32_BE)
#define VSUPPORTED_AFMT \
(AFMT_S16_BE | AFMT_S16_LE | AFMT_U16_BE | AFMT_U16_LE | \
AFMT_S24_BE | AFMT_S24_LE | AFMT_U24_BE | AFMT_U24_LE | \
AFMT_S32_BE | AFMT_S32_LE | AFMT_U32_BE | AFMT_U32_LE | \
AFMT_F32_BE | AFMT_F32_LE | \
AFMT_U8 | AFMT_S8)
#define VVOLUME_UNIT_SHIFT 7
struct virtual_profile;
typedef TAILQ_ENTRY(virtual_profile) vprofile_entry_t;
typedef TAILQ_HEAD(, virtual_profile) vprofile_head_t;
typedef struct virtual_profile vprofile_t;
struct virtual_client;
typedef TAILQ_ENTRY(virtual_client) vclient_entry_t;
typedef TAILQ_HEAD(, virtual_client) vclient_head_t;
typedef struct virtual_client vclient_t;
struct virtual_monitor;
typedef TAILQ_ENTRY(virtual_monitor) vmonitor_entry_t;
typedef TAILQ_HEAD(, virtual_monitor) vmonitor_head_t;
typedef struct virtual_monitor vmonitor_t;
struct virtual_resample;
typedef struct virtual_resample vresample_t;
struct cuse_methods;
struct virtual_compressor {
uint8_t enabled;
uint8_t knee;
uint8_t attack;
uint8_t decay;
};
struct virtual_profile {
vprofile_entry_t entry;
vclient_head_t head;
char oss_name[VMAX_STRING];
char wav_name[VMAX_STRING];
uint32_t rx_filter_size;
uint32_t tx_filter_size;
double *rx_filter_data[VMAX_CHAN];
double *tx_filter_data[VMAX_CHAN];
int64_t rx_peak_value[VMAX_CHAN];
int64_t tx_peak_value[VMAX_CHAN];
int8_t rx_shift[VMAX_CHAN];
int8_t tx_shift[VMAX_CHAN];
uint8_t rx_src[VMAX_CHAN];
uint8_t tx_dst[VMAX_CHAN];
uint8_t rx_mute[VMAX_CHAN];
uint8_t tx_mute[VMAX_CHAN];
uint8_t rx_pol[VMAX_CHAN];
uint8_t tx_pol[VMAX_CHAN];
uint8_t bits;
uint8_t channels;
struct virtual_compressor rx_compressor_param;
double rx_compressor_gain[VMAX_CHAN];
uint8_t synchronized;
uint32_t rec_delay;
int fd_sta;
struct {
const char * host;
const char * port;
const char * rtp_ifname;
const char * rtp_port;
volatile struct http_state * state;
size_t nstate;
int rtp_fd;
int rtp_vlanid;
uint32_t rtp_ts;
uint16_t rtp_seqnum;
} http;
};
struct virtual_ring {
uint8_t *buf_start;
uint32_t pos_read;
uint32_t total_size;
uint32_t len_write;
};
struct virtual_resample {
SRC_DATA data;
SRC_STATE *state;
float *data_in;
float *data_out;
};
struct virtual_client {
vclient_entry_t entry;
uint32_t tx_filter_offset;
uint32_t rx_filter_offset;
int64_t *tx_filter_in[VMAX_CHAN];
int64_t *rx_filter_in[VMAX_CHAN];
double *tx_filter_out[VMAX_CHAN];
double *rx_filter_out[VMAX_CHAN];
struct virtual_ring rx_ring[2];
struct virtual_ring tx_ring[2];
vresample_t rx_resample;
vresample_t tx_resample;
struct virtual_profile *profile;
uint64_t rx_samples;
uint64_t rx_timestamp;
uint64_t tx_samples;
uint64_t tx_timestamp;
uint32_t buffer_frags;
uint32_t buffer_size;
uint32_t low_water;
uint32_t rec_delay;
uint32_t rx_noise_rem;
uint32_t tx_noise_rem;
int rx_busy;
int tx_busy;
int channels;
int format;
int rx_enabled;
int tx_enabled;
int rx_volume;
int tx_volume;
int type;
int sample_rate;
uint32_t buffer_size_set:1;
uint32_t buffer_frags_set:1;
uint32_t sync_busy:1;
uint32_t sync_wakeup:1;
int padding:28;
};
struct virtual_monitor {
vmonitor_entry_t entry;
int64_t peak_value;
uint8_t src_chan;
uint8_t dst_chan;
uint8_t pol;
uint8_t mute;
int8_t shift;
};
extern vprofile_head_t virtual_profile_client_head;
extern vprofile_head_t virtual_profile_loopback_head;
extern vmonitor_head_t virtual_monitor_input;
extern vmonitor_head_t virtual_monitor_local;
extern vmonitor_head_t virtual_monitor_output;
extern const struct cuse_methods vctl_methods;
extern struct virtual_compressor voss_output_compressor_param;
extern double voss_output_compressor_gain[VMAX_CHAN];
extern int64_t voss_output_peak[VMAX_CHAN];
extern int64_t voss_input_peak[VMAX_CHAN];
extern uint32_t voss_jitter_up;
extern uint32_t voss_jitter_down;
extern uint32_t voss_max_channels;
extern uint32_t voss_mix_channels;
extern uint32_t voss_dsp_samples;
extern uint32_t voss_dsp_max_channels;
extern uint32_t voss_dsp_sample_rate;
extern uint32_t voss_dsp_bits;
extern uint8_t voss_libsamplerate_enable;
extern uint8_t voss_libsamplerate_quality;
extern int voss_is_recording;
extern int voss_has_synchronization;
extern char voss_dsp_rx_device[VMAX_STRING];
extern char voss_dsp_tx_device[VMAX_STRING];
extern char voss_ctl_device[VMAX_STRING];
extern volatile sig_atomic_t voss_exit;
extern int vring_alloc(struct virtual_ring *, size_t);
extern void vring_free(struct virtual_ring *);
extern void vring_reset(struct virtual_ring *);
extern void vring_get_read(struct virtual_ring *, uint8_t **, size_t *);
extern void vring_get_write(struct virtual_ring *, uint8_t **, size_t *);
extern void vring_inc_read(struct virtual_ring *, size_t);
extern void vring_inc_write(struct virtual_ring *, size_t);
extern size_t vring_total_read_len(struct virtual_ring *);
extern size_t vring_total_write_len(struct virtual_ring *);
extern size_t vring_write_linear(struct virtual_ring *, const uint8_t *, size_t);
extern size_t vring_read_linear(struct virtual_ring *, uint8_t *, size_t);
extern size_t vring_write_zero(struct virtual_ring *, size_t);
extern vclient_t *vclient_alloc(void);
extern void vclient_free(vclient_t *);
extern int vclient_get_default_fmt(vprofile_t *, int type);
extern int vclient_setup_buffers(vclient_t *, int size, int frags,
int channels, int format, int sample_rate);
extern int vclient_export_read_locked(vclient_t *);
extern void vclient_import_write_locked(vclient_t *);
extern uint32_t vclient_sample_bytes(vclient_t *);
extern uint32_t vclient_bufsize_internal(vclient_t *);
extern uint32_t vclient_bufsize_scaled(vclient_t *);
extern int64_t vclient_noise(uint32_t *, int64_t, int8_t);
extern vmonitor_t *vmonitor_alloc(int *, vmonitor_head_t *);
extern uint32_t format_best(uint32_t);
extern void format_import(uint32_t, const uint8_t *, uint32_t, int64_t *);
extern void format_export(uint32_t, const int64_t *, uint8_t *, uint32_t);
extern int64_t format_max(uint32_t);
extern void format_maximum(const int64_t *, int64_t *, uint32_t, uint32_t, int8_t);
extern void format_remix(int64_t *, uint32_t, uint32_t, uint32_t);
extern void format_silence(uint32_t, uint8_t *, uint32_t);
extern void *virtual_oss_process(void *);
extern uint32_t voss_ad_last_delay;
extern uint32_t voss_dsp_rx_refresh;
extern uint32_t voss_dsp_tx_refresh;
extern uint8_t voss_ad_enabled;
extern uint8_t voss_ad_output_signal;
extern uint8_t voss_ad_input_channel;
extern uint8_t voss_ad_output_channel;
extern void voss_ad_reset(void);
extern void voss_ad_init(uint32_t);
extern double voss_ad_getput_sample(double);
extern void voss_add_options(char *);
extern uint64_t virtual_oss_delay_ns(void);
extern void virtual_oss_wait(void);
extern uint64_t virtual_oss_timestamp(void);
extern void voss_x3_multiply_double(const int64_t *, const double *, double *, const size_t);
extern void vclient_tx_equalizer(struct virtual_client *, int64_t *, size_t);
extern void vclient_rx_equalizer(struct virtual_client *, int64_t *, size_t);
extern int vclient_eq_alloc(struct virtual_client *);
extern void vclient_eq_free(struct virtual_client *);
extern void voss_compressor(int64_t *, double *, const struct virtual_compressor *,
const unsigned, const unsigned, const int64_t);
extern const char *voss_httpd_start(vprofile_t *);
#endif